提问人:Destructor 提问时间:10/22/2015 最后编辑:Peter MortensenDestructor 更新时间:10/24/2015 访问量:4910
为什么 'int ;' 在 C 中编译良好,但在 C++ 中编译不行?
Why does `int ;` compile fine in C, but not in C++?
问:
请考虑以下程序(在此处查看现场演示)。
#include <stdio.h>
int main(void)
{
int ; // Missing variable name
puts("Surprise");
}
我的编译器 gcc 4.8.1 给出以下警告:
[警告] 空声明中的无用类型名称 [默认启用]
为什么它编译良好?我不应该得到编译器错误吗?g++ 4.8.1 在我将其编译为 C++ 程序时出现以下错误:
[错误] 声明不声明任何内容 [-fpermissive]
答:
声明的语法定义为(省略 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
请注意,声明说明符是递归定义的,但每个带有 opt 的说明符都表示它是可选的。
此外,以下第 6 条规定:
声明说明符由一系列指示链接的说明符组成, 存储持续时间,以及声明符所表示的实体类型的部分。initdeclarator-list 是以逗号分隔的声明符序列,每个声明符可能具有其他类型信息和/或初始值设定项。声明符包含要声明的标识符(如果有)。
请注意单词(如果有)。
C标准说
除static_assert声明外,声明应至少声明一个声明符(函数的参数或结构或联合的成员除外)、标记或枚举的成员。
C++ 说
在简单声明中,只有在声明类(子句 9)或枚举时,才能省略可选的 init-declarator-list。
在任何一种语言中,违反这一点都需要诊断。这些标准不讨论编译器错误或警告。警告是一种诊断。
评论
struct { int a; };
struct a { ... }
struct { ...} a
您的代码在 C 和 C++ 中都是非法的(即错误、格式错误、违反约束)。在一种语言中收到“警告”而在另一种语言中收到“错误”的原因只是编译器和编译器设置的一个怪癖。毕竟,这两种语言都没有真正正式区分“警告”和“错误”。默认设置下的 GCC 恰好在 C 模式下更宽松(主要是出于历史原因)。
在 GCC 中使用,您也会在 C 代码中得到“错误”。(请注意,不要简单地盲目地将所有“警告”变成“错误”。它尝试仅将实际的约束冲突报告为“错误”。-pedantic-errors
-pedantic-errors
评论
int a, b, c;
int ;
-Werror