декларация ничего не объявляет: предупреждение?

#include  #include  #include  int main() { struct emp { struct address { int a; }; struct address a1; }; } 

Этот код показывает предупреждение: –

warning: декларация ничего не объявляет (включена по умолчанию)

Если в следующем коде не отображается предупреждение

 #include  #include  #include  int main() { struct emp { struct address { int a; }a1; }; } 

Почему «предупреждение» отображается только в первом коде?

Причина, по которой компилятор показывает предупреждение, состоит в том, что он не видит имя переменной address типа, которую вы определили для структуры emp , даже если вы объявляете что-то, используя address на следующей строке, но я думаю, что компилятор не достаточно умный, чтобы понять это.

Как вы показали, это вызывает предупреждение:

 struct emp { struct address {}; // This statement doesn't declare any variable for the emp struct. struct address a1; }; 

Но не это:

 struct emp { struct address {} a1; // This statement defines the address struct and the a1 variable. }; 

Или это:

 struct address {}; struct emp { struct address a1; //the only statement declare a variable of type struct address }; 

Структура struct emp {} не отображает никаких предупреждений, так как этот оператор не находится внутри блока детекции структуры. Если вы положили его внутри одного из них, тогда компилятор также покажет предупреждение. Ниже приводятся два предупреждения:

 struct emp { struct phone {}; struct name {}; }; 

Синтаксис определения структуры:

 struct identifier { type member_name; // ... }; 

Если вы добавите идентификатор сразу после закрытия фигурной скобки, вы объявляете переменную с указанной структурой.

В вашем первом примере компилятор рассматривает address struct как тип члена. это похоже на то, что вы пишете:

 struct identifier { type ; // No member name is specified type a1; // ... } 

Но во втором примере вы указали имя участника:

 struct identifier { type a1; // Member name specified // ... } 

И вот пример предупреждения: http://ideone.com/KrnYiE .

Причина, по которой отображается предупреждение, заключается в том, что первый отрывок не является правильным. C – он имеет ограничение ограничения, которое компилятор C, соответствующий стандартам, должен выдать диагностическое сообщение. Он нарушает C11 6.7.2.1p2 :

Ограничения

  1. Объявление структуры, которое не объявляет анонимную структуру или анонимный союз, должно содержать список struct-declarator .

Это означает, что это нормально писать

 struct foo { struct { int a; }; }; 

так как внутренняя struct объявляет анонимную структуру, то есть она не называется.

Но в вашем примере struct address имеет имя- address – и, следовательно, он должен иметь список деклараторов после того, как список закрывающих списков фигур, например, a1 как в вашем примере, или более сложный foo, *bar, **baz[23][45] .