Czy może int (*)[]
być niekompletny?
C 2018 6.2.5 1 mówi:
W różnych punktach w jednostce tłumaczenia typ obiektu może być niekompletny (brak wystarczających informacji, aby określić rozmiar obiektów tego typu) lub kompletny (posiadający wystarczające informacje).
Wydaje się więc, że jeśli znany jest rozmiar typu, typ jest kompletny. 6.2.6.1 28 określa, że niektóre typy wskaźników muszą mieć takie same rozmiary (wskaźniki do void
i znaki, wskaźniki do kompatybilnych typów, wskaźniki do struktur i wskaźniki do związków), ale wskaźniki do innych typów mogą się różnić.
W implementacji C, w której wszystkie wskaźniki lub wszystkie wskaźniki tablic int
mają ten sam rozmiar, wówczas rozmiar int (*)[]
jest znany, więc byłby kompletny. W implementacji, która, powiedzmy, używa różnych wskaźników dla dużych tablic, rozmiar nie byłby znany, więc jest niekompletny.
Jak wskazuje MM , struktura nie może zawierać elementu niepełnego typu, z wyjątkiem końcowego elastycznego elementu tablicy, zgodnie z ograniczeniem w 6.7.2.1 3. Sugeruje to, że implementacja z jednym rozmiarem wskaźników musi zaakceptować, struct { int (*p)[]; }
podczas gdy implementacja ma inny rozmiary takich tablic muszą zdiagnozować naruszenie ograniczenia. (To z kolei oznacza, że taka deklaracja nie jest częścią ściśle zgodnego C.)
źródło
void *
jest kompletny, pokazuje, że wskaźnik do niekompletnego typu może być kompletny. Nie pokazuje, czy wskaźnik do niekompletnego typu może być niekompletny. Gdyby ktoś zapytał „Czy ssak może być słoniem?”, Wykazanie, że „Lew jest ssakiem” nie zapewniłoby, że ssak nie może być słoniem. Pytanie dotyczy tego, czy zestaw X wskaźników typu niepełnego może zawierać niekompletny element. Nie ma znaczenia, że zestaw X wskaźników do niepełnego typu zawiera element, który jest kompletny.Odpowiedzi:
Tablica o nieznanym rozmiarze jest niekompletna:
Typ
int (*)[]
nie jest jednak niekompletny: jest wskaźnikiem tablicyint
o nieznanym rozmiarze.Wskaźnik ma dobrze znany rozmiar:
Ponadto możesz nawet wyrejestrować to, dzięki semantyce tablic:
Edytować
Ponadto wskaźnik jest zawsze kompletnym typem. Jest napisany czarno na białym w 6.2.5 / 20:
źródło
printf
pokazuje tylko, że wskaźnik do niekompletnej tablicy jest kompletny w implementacji, w której został wykonany, jak stwierdzono w pytaniu - gdyby nie wersja 6.2.5 20, cytowana w ostatnim akapicie, kompilacja może się nie powieść. 6.2.5 23 również nie ma znaczenia; informuje nas, że rozmiar jest znany i stały, jeśli jest kompletny, i wiemy już, że bycie kompletnym oznacza, że rozmiar jest znany.int
muszą mieć taki sam rozmiar, a wszystkie wskaźniki do tablic określonegostruct
muszą mieć taki sam rozmiar, chociaż być może nie wszystkie wskaźniki do tablic różnego rodzajustruct
muszą mieć ten sam rozmiar jak siebie nawzajem.T(*)[]
musi mieć ten sam rozmiar coT(*)[5]
, ponieważ są one kompatybilnymi typami i możemy dodawać lub usuwać kwalifikatory