Почему указатели на неопределенные структуры иногда нелегальны в C и C ++ - PullRequest
8 голосов
/ 04 мая 2011

Почему

void foo(T*);

недопустимо как в C, так и в C ++ (потому что T не определено), тогда как

void foo(struct T*);

допустимо, хотя все еще не определить T?Есть ли ситуации, в которых это имеет семантическое значение для вызывающей стороны, является ли T структурой или каким-либо другим типом (class / enum / typedef / etc.)?

Ответы [ 4 ]

5 голосов
/ 04 мая 2011

В C, потому что все указатели на структуры (любые структуры) имеют одинаковую ширину и свойства выравнивания

6.2.5 / 27 ( Стандарт C99 )

Указатель на void должен иметь то же представление и требования выравнивания как указатель на тип символа. Аналогично, указатели на квалифицированные или неквалифицированные версии совместимые типы должны иметь одинаковое представление и Требования к выравниванию. Все указатели на типы структур должны иметь одинаковое представление и выравнивание требования как друг к другу. Все указатели на типы объединения должны иметь одинаковое представление и выравнивание требования как друг к другу. Указатели на другие типы нужны не имеют одинаковых требований к представлению или выравниванию.


Указатели на что-либо, с другой стороны, могут иметь различные свойства ширины и / или выравнивания (void *, указатели на функции, unsigned char *, ...)

5 голосов
/ 04 мая 2011

void foo(struct T*); одновременно функционирует как прямое объявление struct T в этой области, поэтому можно указывать на него указатель.

В void foo(T*) нет никаких сведений о том, что такое Tдолжно быть.Если оказывается, что это имя переменной, а не типа, то строка кода неверна.C ++ нужно больше информации, прежде чем он сможет сказать, что строка кода верна.

2 голосов
/ 04 мая 2011
struct T

действует как предварительное объявление T. Вы обещаете, что компилятор определит его позже.Если вы действительно что-то делали на T или пытались создать экземпляр, у вас возникли бы проблемы:

  struct T t1; //error, incomplete type
  struct T* t2; // ok
  t2->foo     // error, incomplete type

Just

 T

- произвольный идентификатор.Это переменная?Это функция?Язык не предоставляет возможности для прямого объявления без добавления struct или class перед переменной.

1 голос
/ 04 мая 2011

struct T объявляет T как struct, даже если оно появляется в более крупном объявлении, то есть объявлении foo. Тип является неполным, но это не имеет значения, когда он используется для объявления параметра функции указателя.

Без struct компилятор ничего не знает о том, что T должно быть.

Если T ранее был объявлен как struct, тогда void foo(T*) будет разрешен в C ++, но не в C, потому что имена struct s автоматически не становятся именами типов, хотя вы можете объявить typedef с идентичным именем в Си, если хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...