Декларация ничего не объявляет: предупреждение?
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int main()
{
struct emp
{
struct address
{
int a;
};
struct address a1;
};
}
Этот код показывает предупреждение: -
warning: объявление не объявляет ничего (включено по умолчанию)
Если в следующем коде не отображается предупреждение
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int main()
{
struct emp
{
struct address
{
int a;
}a1;
};
}
Почему "предупреждение" отображается только в первом коде?
Ответы
Ответ 1
Причина, по которой компилятор показывает предупреждение, состоит в том, что он не видит имя переменной типа address
, которую вы определили для структуры emp
, даже если вы do объявите что-то использует 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 {};
};
Ответ 2
Синтаксис определения структуры:
struct identifier {
type member_name;
// ...
};
Если вы добавите идентификатор сразу после закрытия фигурной скобки, вы объявляете переменную с указанной структурой.
В вашем первом примере компилятор рассматривает структуру address
как тип члена. это нравится, если вы пишете:
struct identifier {
type ; // No member name is specified
type a1;
// ...
}
Но во втором примере вы указали имя члена:
struct identifier {
type a1; // Member name specified
// ...
}
И вот пример предупреждения: http://ideone.com/KrnYiE.
Ответ 3
Причина, по которой отображается предупреждение, заключается в том, что первый отрывок не является правильным. C - он имеет ограничение ограничения, которое компилятор C, соответствующий стандартам, должен выдать диагностическое сообщение. Он нарушает C11 6.7.2.1p2:
Ограничения
- Объявление структуры, которое не объявляет анонимную структуру или анонимный союз, должно содержать список struct-declarator.
Это означает, что это нормально писать
struct foo {
struct {
int a;
};
};
так как внутренняя struct
объявляет анонимную структуру, то есть она не называется.
Но в вашем примере struct address
имеет имя- address
- и, следовательно, он должен иметь список деклараторов после того, как список закрывающих списков фигур, например, a1
как в вашем примере, или более сложный foo, *bar, **baz[23][45]
.