The IAR Embedded C compiler is happy with this, and I assumed it was correct C code:
struct incomplete;
typedef struct incomplete (*why_not)[2];
struct incomplete {struct incomplete *known_to_work;} array[2];
why_not ok = &array;
However, gcc and clang choke on the definition of why_not
:
incomplete.c:2:29: error: array type has incomplete element type ‘struct incomplete’
typedef struct incomplete (*why_not)[2];
^
Technically, there is no reason to reject a definition of a "pointer to array of incomplete" type. After all, the structure definition is needed only where such a variable is dereferenced, or some pointer arithmetics is performed.
I'm eager to hide structure definitions where possible.
What does the C standard say about this?
An incomplete type is a type that describes an identifier but lacks information needed to determine the size of the identifier. An incomplete type can be: A structure type whose members you have not yet specified. A union type whose members you have not yet specified.
In simple words, array names are converted to pointers. That's the reason why you can use pointers to access elements of arrays. However, you should remember that pointers and arrays are not the same. There are a few cases where array names don't decay to pointers.
So when you have a pointer that points to a block of memory, such as an array or a part of an array, you can treat that pointer ``as if'' it were an array, using the convenient [i] notation.
An incomplete class declaration is a class declaration that does not define any class members. You cannot declare any objects of the class type or refer to the members of a class until the declaration is complete.
The code uses an array declarator where the element type is incomplete. This a constraint violation in ISO C, according to 6.7.6.2/1 Array declarators:
Constraints
In addition to optional type qualifiers and the keyword static, the
[
and]
may delimit an expression or*
. If they delimit an expression (which specifies the size of an array), the expression shall have an integer type. If the expression is a constant expression, it shall have a value greater than zero. The element type shall not be an incomplete or function type.
The following statement
typedef struct incomplete (*why_not)[2];
is a pointer to an array of two struct incomplete
. The compiler does not know the size of struct incomplete
yet, since it is not yet defined.
The following will however work:
typedef struct incomplete *why_not[2];
i.e.: an array of pointers to struct incomplete
. The compiler does know the size of a pointer to an incomplete type (i.e.: it is just the size needed to store an address).
Edit:
The compiler does not need to know the size of struct incomplete
in either case (as long as no pointer arithmetic is taking place), since both declarations are just declaring pointers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With