62

Consider the following program (see live demo here).

#include <stdio.h>
int main(void)
{
      int ;  // Missing variable name
      puts("Surprise");
}

My compiler, gcc 4.8.1, gives the below warning:

[Warning] useless type name in empty declaration [enabled by default]

Why does it compile fine? Shouldn't I get a compiler error? g++ 4.8.1 gives the following error when I compile it as a C++ program:

[Error] declaration does not declare anything [-fpermissive]

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Destructor
  • 14,123
  • 11
  • 61
  • 126
  • 1
    @Nawaz: Is it explicitly said by language specification? – Destructor Oct 22 '15 at 04:47
  • 1
    It's useless, I'd be surprised if the compiler omitted any instructions for that empty declaration. – Elliott Frisch Oct 22 '15 at 04:52
  • 3
    It is explicitly said by the C++ standard: "**[dcl.dcl]/5** In a *simple-declaration*, the optional *init-declarator-list* can be omitted only when declaring a class (Clause 9) or enumeration (7.2), that is, when the *decl-specifier-seq* contains either a *class-specifier*, an *elaborated-type-specifier* with a *class-key* (9.1), or an *enum-specifier*." I'm not familiar with the C standard sufficiently well to cite chapter and verse. – Igor Tandetnik Oct 22 '15 at 04:54
  • 33
    "produces warning" is not "compiles fine". – n. m. could be an AI Oct 22 '15 at 05:13
  • Who would want to write `int;` and compile his code? I dont see what the fuss is all about. – machine_1 Oct 22 '15 at 05:27
  • The names of unused parameters may be omitted, it suppresses the unused parameter warning. This is the local-variable equivalent of the same thing. I would not want that to compile cleanly though, it is definitely worthy of a warning. It looks like a typo. – doug65536 Oct 22 '15 at 05:34
  • 8
    Well, you can define multiple locals at the same time (`int a, b, c;`), right? `int ;` just looks like a special case of the same thing, with 0 declared locals :D – Luaan Oct 22 '15 at 12:31
  • @Luaan: ... And that special case is explicitly outlawed by the standard in both C and C++. – AnT stands with Russia Oct 22 '15 at 14:25
  • 2
    Recompile with `-Werror` – David Conrad Oct 22 '15 at 23:07

3 Answers3

50

The C standard says

A declaration other than a static_assert declaration shall declare at least a declarator (other than the parameters of a function or the members of a structure or union), a tag, or the members of an enumeration.

C++ says

In a simple-declaration, the optional init-declarator-list can be omitted only when declaring a class (Clause 9) or enumeration.

A violation of this in either language requires a diagnostic. The standards do not talk about compiler errors or warnings. A warning is a diagnostic.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
  • Could you clarify whether the standard requires translation to fail on certain violations? An "error" could be defined as a violation that produces a diagnostic and failure, and a "warning" is one that produces a diagnostic and no failure. – Damian Yerrick Oct 22 '15 at 15:24
  • 4
    @tepples No, the standard only requires a diagnostic. It doesn't require (but allows) an invalid program to be rejected. – n. m. could be an AI Oct 22 '15 at 15:44
  • 1
    it means that e.g. `struct { int a; };` declares a struct member, but this is not enough. – n. m. could be an AI Oct 23 '15 at 22:54
  • @n.m.: so name of structure is necessary here. right? – Destructor Oct 24 '15 at 08:41
  • 1
    Either a tag or a declarator is needed. Tag is `struct a { ... }`. and declarator is `struct { ...} a`. A declarator can be a variable name or a typedef name (if there's typedef keyword). – n. m. could be an AI Oct 24 '15 at 11:41
36

Your code is illegal (i.e. erroneous, ill-formed, constraint-violating) in both C and C++. The reason you get a "warning" in one language and "error" in another is just a quirk of your compiler and your compiler setup. After all, neither language really formally differentiates between "warnings" and "errors". GCC under its default settings just happens to be more permissive in C mode (mostly for historical reasons).

Use -pedantic-errors in GCC, and you will get an "error" in C code as well. (Note that -pedantic-errors does not simply blindly turn all "warnings" into "errors". It attempts to report only actual constraint violations as "errors".)

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
18

The syntax of declaration is defined as (omitting init-declarator-list and init-declarator):

C11 6.7 Declarations

declaration:
    declaration-specifiers init-declarator-list opt ;
    static_assert-declaration
declaration-specifiers:
    storage-class-specifier declaration-specifiers opt
    type-specifier declaration-specifiers opt
    type-qualifier declaration-specifiers opt
    function-specifier declaration-specifiers opt
    alignment-specifier declaration-specifiers opt

Note that declaration-specifiers is defined recursively, but each with an opt indicates it's optional.

Also, the following clause 6 states:

The declaration specifiers consist of a sequence of specifiers that indicate the linkage, storage duration, and part of the type of the entities that the declarators denote. The initdeclarator-list is a comma-separated sequence of declarators, each of which may have additional type information, or an initializer, or both. The declarators contain the identifiers (if any) being declared.

Note the words if any.

Community
  • 1
  • 1
Yu Hao
  • 119,891
  • 44
  • 235
  • 294