declaration does not declare anything : warning?

2019-03-25 08:22发布

问题:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

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

This code shows a warning:-

warning : declaration does not declare anything (enabled by default)

Where as the following code shows no warning

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

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

Why 'warning' is displayed in the first code only?

回答1:

The reason why the compiler is showing the warning is because it doesn't see a name for the variable of type address you defined for the emp struct, even though you do declare something using address on the next line, but I guess the compiler is not smart enough to figure that out.

As you showed, this produces a warning:

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

But not this:

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

Or this:

struct address {};

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

The struct emp {} doesn't show any warnings since this statement is not inside a struct defintion block. If you did put it inside one of those then the compiler will show a warning for that as well. The following will show two warnings:

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


回答2:

The reason the warning is displayed is that the first excerpt is not proper C - it has a constraint violation that a standards-compliant C compiler must produce a diagnostisc message for. It violates the C11 6.7.2.1p2:

Constraints

  1. A struct-declaration that does not declare an anonymous structure or anonymous union shall contain a struct-declarator-list.

Meaning that it is OK to write

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

since the inner struct declares an anonymous structure, i.e. it is not named.

But in your example the struct address has a name - address - and therefore it must have a declarator list after the closing brace - declarator list being for example a1 as in your example, or more complex foo, *bar, **baz[23][45].



回答3:

The syntax of a structure definition is:

struct identifier {
    type member_name;

    // ...

};

If you add an identifier just after the closing curly brace, you're declaring a variable with that defined struct.

In your first example the compiler consider the address struct as member type. it's like if you writes:

struct identifier {

    type ; // No member name is specified
    type a1;

    // ...

}

But in the second example you specified the member name:

struct identifier {

    type a1; // Member name specified

    // ...

}

And here is an example of the warning: http://ideone.com/KrnYiE.