1

Why does C allows empty declarations? They're both explicitly allowed at the grammar level and only generate a warning if compiled.

The production declaration, from the Annex A of the C standard, is allowing it at the grammar level:

declaration
    = declaration_specifiers , ";"
    | declaration_specifiers , init_declarator_list , ";"
    | static_assert_declaration
    ;

(turned into EBNF by me)

Leandros
  • 16,805
  • 9
  • 69
  • 108
  • Because they're useful? Isn't `struct tagS { int x; };` formally an empty declaration? – Ben Voigt Jan 26 '17 at 19:26
  • 1
    What version of the standard are you looking at? C11 only shows the second and third options. – dbush Jan 26 '17 at 19:28
  • @BenVoigt Right! Yes, that's formally an empty declaration. structs are solely handled as declaration_specifiers => type_specifier => struct_or_union specifier. – Leandros Jan 26 '17 at 19:37
  • @Leandros: And it's really hard to capture "you have to do at least one non-trivial thing, but it could be either in the specifiers, or in the declarator list" as a grammar construct... so it's a non-grammar syntax rule. See http://stackoverflow.com/a/33273777/103167 – Ben Voigt Jan 26 '17 at 19:38
  • @dbush C11 shows exactly what is shown above. The `init_declarator_list` is marked as optional. – Leandros Jan 27 '17 at 10:18

1 Answers1

5

C does not allow empty declarations. See https://stackoverflow.com/a/33273777/103167

But it does allow declarations without any declarators, only specifiers, as long as those specifiers create a type tag. For example:

/* here begins the specifier */
struct tagS /* <-- there's the tag */
{
   int x;
} /* here ends the specifier */
/* no declarators */
;

Which is a perfectly useful and legal way to define the structure of a user-defined type.

And that's why the grammar has to specify the declarator list as optional.

Community
  • 1
  • 1
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • My confusion didn't came from struct declaration, but from the fact that simply `int;` is a valid declaration. – Leandros Jan 27 '17 at 08:30
  • @Leandros: It is not valid, because it has neither declarator nor tag nor defines any enumeration members. See the linked answer. – Ben Voigt Jan 27 '17 at 16:19
  • 1
    While not being valid semantically, it is valid at the grammar level. – Leandros Jan 27 '17 at 17:16
  • @Leandros `int;` is syntactically not a valid declaration because the constraint violation which forbids it has a purely syntactic interpretation, just like the one that forbids `unsigned double`. The rule is that a declaration must have at least a declarator, or a tag, or enumerators. Those are pieces of syntax; effectively, this is a grammar rule. A more complicated set of grammar rules could be written to replace this constraint rule. – Kaz Dec 30 '21 at 07:11
  • So that is to say, the grammar could have separate rules for (1) a struct declaration with no tag, but at least one mandatory declarator: (2) a struct declaration with a tag and optional declarators; (3) an enum declaration with optional declarators, (4) non-struct/union, non-enum specifiers with at least one declarator. – Kaz Dec 30 '21 at 07:14