为什么 `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-listinit-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" .)