Peut int (*)[]
être un type incomplet?
C 2018 6.2.5 1 dit:
À divers points d'une unité de traduction, un type d'objet peut être incomplet (manque d'informations suffisantes pour déterminer la taille des objets de ce type) ou complet (avoir suffisamment d'informations).
Il semble donc que si la taille d'un type est connue, le type est complet. 6.2.6.1 28 spécifie que certains types de pointeurs doivent avoir les mêmes tailles (pointeurs vers void
et caractères, pointeurs vers des types compatibles, pointeurs vers des structures et pointeurs vers des unions), mais les pointeurs vers d'autres types peuvent varier.
Dans une implémentation C où tous les pointeurs, ou tous les pointeurs vers des tableaux de int
, ont la même taille, alors la taille de int (*)[]
est connue, elle serait donc complète. Dans une implémentation qui, par exemple, utilise différents pointeurs pour les grands tableaux, la taille ne serait pas connue, elle est donc incomplète.
Comme le souligne MM , une structure ne doit pas contenir de membre de type incomplet, à l'exception d'un membre de tableau flexible final, conformément à une contrainte du 6.7.2.1 3. Cela suggère qu'une implémentation avec une taille de pointeurs doit accepter struct { int (*p)[]; }
tandis qu'une implémentation qui a différents les tailles de ces tableaux doivent diagnostiquer une violation de contrainte. (Cela signifie à son tour qu'une telle déclaration ne fait pas partie d'un C. strictement conforme.)
la source
void *
soit complet montre qu'un pointeur vers un type incomplet peut être complet. Il ne montre pas si un pointeur vers un type incomplet peut être incomplet. Si l'on demandait «Un mammifère peut-il être un éléphant?», Montrer que «Un lion est un mammifère» ne signifierait pas qu'un mammifère ne peut pas être un éléphant. La question demande si l'ensemble X de pointeurs de type incomplet peut contenir un élément incomplet. Il n'est pas pertinent de montrer que l'ensemble X de pointeurs sur type incomplet contient un élément complet.Réponses:
Un tableau de taille inconnue est incomplet:
Le type
int (*)[]
n'est cependant pas incomplet: c'est un pointeur d'un tableau deint
taille inconnue.Et un pointeur a une taille bien connue:
De plus, vous pouvez même le déréférencer, grâce à la sémantique du tableau:
Éditer
De plus, un pointeur est toujours un type complet. Il est écrit noir sur blanc en 6.2.5 / 20:
la source
printf
montre seulement qu'un pointeur vers un tableau incomplet est complet dans l'implémentation dans laquelle il a été exécuté, comme indiqué dans la question - s'il ne s'agissait pas de 6.2.5 20, cité dans le dernier paragraphe, il pourrait ne pas être compilé. 6.2.5 23 n'est pas non plus pertinent; il nous dit que la taille est connue et constante si elle est complète, et nous savons déjà qu'être complet signifie que la taille est connue.int
doivent avoir la même taille les uns par rapport aux autres, et tous les pointeurs vers des tableaux d'un certainstruct
doivent avoir la même taille les uns par rapport aux autres, bien que tous les pointeurs vers des tableaux de types différents nestruct
doivent pas nécessairement avoir la même taille comme les uns des autres.T(*)[]
doit avoir la même taille queT(*)[5]
, car ce sont des types compatibles et nous pourrions ajouter ou supprimer des qualificatifs