GCC: array type has incomplete element type?

2019-06-05 05:26发布

问题:

GCC gives me an "array type has incomplete element type"-error message when i try to compile this:

typedef struct _node node;
struct _node{
 int foo;
 node (*children)[2];
 int bar;
};

In memory the struct should look like this

0x345345000000 foo
0x345345000004 pointer to 1. child node
0x345345000008 pointer to 2. child node
0x34534500000C bar

回答1:

That's because the C type expression works the other way round.

This:

node (*children)[2];

reads as the following: the contents of children, when dereferenced (* is applied to them), yield something on which the array operator [] can be applied, yielding a node. Which means that children is a pointer to an array of two node. However, you do not want a pointer to an array, you want an array of two pointers. For that, you should put the parentheses thus:

node *(children[2]);

which then reads as: the contents of children are an array of two values; applying * on one of them yields a node. This is what you want: an array of two pointers to node. Note that this is equivalent to:

node *children[2];

because in the C syntax, when it comes to type expressions, the [] operator takes precedence over the * operator.

In your initial version, the C compiler grumbles because at the time it reads the declaration, it does not know what size node is (the structure definition is not complete yet), and, as such, has trouble imagining a type "array of two node". This is a rather indirect symptom of the problem.

Side note: you should refrain from using _node or any other identifier beginning with an underscore in your code. These identifiers are reserved for "the implementation". In practice, system headers may use them, and collisions could prove harmful. Personally, I tend to add the underscore at the end, like this: typedef struct node_ node;



回答2:

Instead of this:

 node (*children)[2];

Use this:

 struct _node* children[2];