为什么 `int ;` 在 C 中编译良好,但在 C++ 中却不行?
Why does `int ;` compile fine in C, but not in C++?
考虑以下程序(查看现场演示 here)。
#include <stdio.h>
int main(void)
{
int ; // Missing variable name
puts("Surprise");
}
我的编译器 gcc 4.8.1 发出以下警告:
[Warning] useless type name in empty declaration [enabled by default]
为什么编译正常?我不应该得到一个编译器错误吗?当我将 g++ 4.8.1 编译为 C++ 程序时出现以下错误:
[Error] declaration does not declare anything [-fpermissive]
声明的语法定义为(省略init-declarator-list和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
请注意 declaration-specifiers 是递归定义的,但每个都带有 opt 表示它是可选的。
此外,以下第 6 条规定:
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.
注意如果有的话。
C 标准说
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++ 说
In a simple-declaration, the optional init-declarator-list can be omitted only when declaring a class (Clause 9) or enumeration.
任何一种语言的违反都需要诊断。这些标准不讨论编译器错误或警告。警告是诊断。
您的代码在 C 和 C++ 中都是非法的(即错误的、格式错误的、违反约束的)。你在一种语言中得到 "warning" 而在另一种语言中得到 "error" 的原因只是你的编译器和编译器设置的一个怪癖。毕竟,这两种语言都没有真正正式区分 "warnings" 和 "errors"。 GCC 在其默认设置下恰好在 C 模式下更宽松(主要是出于历史原因)。
在 GCC 中使用 -pedantic-errors
,在 C 代码中你也会得到一个 "error"。 (请注意,-pedantic-errors
不会简单地将所有 "warnings" 变成 "errors"。它试图仅报告实际的 约束违规 作为 "errors" .)
考虑以下程序(查看现场演示 here)。
#include <stdio.h>
int main(void)
{
int ; // Missing variable name
puts("Surprise");
}
我的编译器 gcc 4.8.1 发出以下警告:
[Warning] useless type name in empty declaration [enabled by default]
为什么编译正常?我不应该得到一个编译器错误吗?当我将 g++ 4.8.1 编译为 C++ 程序时出现以下错误:
[Error] declaration does not declare anything [-fpermissive]
声明的语法定义为(省略init-declarator-list和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
请注意 declaration-specifiers 是递归定义的,但每个都带有 opt 表示它是可选的。
此外,以下第 6 条规定:
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.
注意如果有的话。
C 标准说
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++ 说
In a simple-declaration, the optional init-declarator-list can be omitted only when declaring a class (Clause 9) or enumeration.
任何一种语言的违反都需要诊断。这些标准不讨论编译器错误或警告。警告是诊断。
您的代码在 C 和 C++ 中都是非法的(即错误的、格式错误的、违反约束的)。你在一种语言中得到 "warning" 而在另一种语言中得到 "error" 的原因只是你的编译器和编译器设置的一个怪癖。毕竟,这两种语言都没有真正正式区分 "warnings" 和 "errors"。 GCC 在其默认设置下恰好在 C 模式下更宽松(主要是出于历史原因)。
在 GCC 中使用 -pedantic-errors
,在 C 代码中你也会得到一个 "error"。 (请注意,-pedantic-errors
不会简单地将所有 "warnings" 变成 "errors"。它试图仅报告实际的 约束违规 作为 "errors" .)