Name | Description | Notes | Source | Availability | |||||||
---|---|---|---|---|---|---|---|---|---|---|---|
void |
Empty type | L | T | Native | C89 | C90 | C95 | C99 | C11 |
Where a declaration for a type is in scope, it is either complete or incomplete. Only array types, structure types, union types and enumeration types can be incomplete, because they can be partially declared, with a full declaration coming later. For example, consider these declarations:
struct point { int x; int y; }; union buff { unsigned char raw[256]; struct packet pkt; }; enum choice { YES, NO, DONTKNOW };
We know how big an object of type struct point
would be, because its
members are listed; similarly for union
buff
. The compiler will know what integer type to choose to
represent all values in enum choice
. Being complete types, they all
have known sizes, which you can get with sizeof(struct point)
, etc.
The following declarations are also permitted:
struct point; union buff; enum choice;
Until a complete declaration comes into scope, these are
incomplete types. This means that sizeof(struct point)
, etc., are all errors, because their sizes
cannot be determined at this stage. Obviously, members of the
structure, union and enumeration types are also inaccessible,
because they are unknown.
It is possible to declare static
objects of these types, but only as pure declarations,
i.e., with extern
and no
initializer:
extern struct point a; extern union buff b; extern enum choice c; /* An array of indeterminate size also has incomplete type. */ extern int arr[];
It's not possible to provide definitions of these objects until the type is complete, but that could be done in a different translation unit.
All pointer types
are complete, even if what they point to is incomplete. Even
with the incomplete types declared above, it is possible to
use the types struct point *
, union buff
*
, etc.,
provided values of these types are not dereferenced and are
not subject to pointer arithmetic.
The members of a structure or union must be of complete types, except for the final member of a structure (in C99 or later), which may be an incomplete array type.
void
is a permanently incomplete
type. No object/variable can ever be declared of
type void
. The type is used in three
ways:
- as the return type of a function returning no value,
- as the parameter list of a zero-parameter function,
- to form the generic pointer type
void *
.