为什么`int;`在C中编译好,但在C ++中没编译?

时间:2015-10-22 04:44:17

标签: c++ c gcc language-lawyer variable-declaration

考虑以下计划(参见现场演示here)。

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

我的编译器gcc 4.8.1给出了以下警告:

  

[警告]空声明中的无用类型名称[默认启用]

为什么编译正常?难道我不会遇到编译错误吗?当我将它编译为C ++程序时,g ++ 4.8.1给出以下错误:

  

[错误]声明未声明任何内容[-fpermissive]

3 个答案:

答案 0 :(得分:48)

C标准说

  

除static_assert声明之外的声明应至少声明一个声明符(除了函数的参数或结构或联合的成员),标记或枚举的成员。

C ++说

  

在一个简单声明中,只有在声明一个类(第9节)或枚举时,才能省略可选的init-declarator-list。

在任何一种语言中违反此要求都需要诊断。标准不讨论编译器错误或警告。警告是诊断。

答案 1 :(得分:34)

您的代码在C和C ++中都是非法的(即错误,格式错误,违反约束)。您在一种语言中获得“警告”而在另一种语言中获得“错误”的原因只是编译器和编译器设置的一个怪癖。毕竟,这两种语言都没有真正正式区分“警告”和“错误”。 GCC在其默认设置下恰好在C模式下更加宽松(主要是出于历史原因)。

在GCC中使用-pedantic-errors,您也会在C代码中收到“错误”。 (请注意,-pedantic-errors不会盲目地将所有“警告”变为“错误”。它会尝试仅将实际的约束违规行为报告为“错误”。)

答案 2 :(得分:18)

声明的语法定义为(省略 init-declarator-list init-declarator ):

  

C11 6.7声明

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

请注意, declaration-specifiers 是递归定义的,但每个 opt 表示它是可选的。

此外,以下第6条规定:

  

声明说明符由一系列指示链接的说明符组成,   存储持续时间,以及声明者表示的实体类型的一部分。 initdeclarator-list是一个以逗号分隔的声明符序列,每个声明符都可以包含其他类型信息,或初始值设定项,或两者兼而有之。声明者包含声明的标识符(如果有的话)

请注意字样