GCC: тип массива имеет неполный тип элемента? - PullRequest
1 голос
/ 16 февраля 2010

GCC выдает мне сообщение об ошибке «тип массива имеет неполный тип элемента», когда я пытаюсь скомпилировать это:

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

В памяти структура должна выглядеть так

Ответы [ 2 ]

7 голосов
/ 16 февраля 2010

Это потому, что выражение типа C работает наоборот.

Это:

node (*children)[2];

читается следующим образом: содержимое children при разыменовании (к ним применяется *) выдает что-то, к чему может быть применен оператор массива [], давая node. Это означает, что children является указателем на массив из двух node. Однако вам не нужен указатель на массив, вам нужен массив из двух указателей. Для этого вы должны поставить круглые скобки так:

node *(children[2]);

, который затем читается как: содержимое children представляет собой массив из двух значений; применение * к одному из них дает node. Это то, что вы хотите: массив из двух указателей на node. Обратите внимание, что это эквивалентно:

node *children[2];

потому что в синтаксисе C, когда речь идет о выражениях типов, оператор [] имеет приоритет над оператором *.

В вашей первоначальной версии компилятор C ворчит, потому что во время чтения объявления он не знает, какой размер node (определение структуры еще не завершено), и, как таковой, испытывает проблемы с представлением введите "массив из двух node". Это довольно косвенный симптом проблемы.

Примечание: вы должны воздерживаться от использования _node или любого другого идентификатора, начинающегося с подчеркивания в вашем коде. Эти идентификаторы зарезервированы для «реализации». На практике системные заголовки могут их использовать, и коллизии могут оказаться вредными. Лично я склоняюсь к подчеркиванию в конце , например: typedef struct node_ node;

2 голосов
/ 16 февраля 2010

Вместо этого:

 node (*children)[2];

Используйте это:

 struct _node* children[2];
...