为什么“-pedantic”现代编译器不再检测到杂散分号?

jer*_*rin 42 c++ gcc clang gcc-pedantic

以下代码片段在添加-pedantic-Werror有点旧的编译器上生成编译错误。

#include <cstdint>
#include <iostream>

int add(int a, int b){
    return a + b;
}; // <-- stray semicolon

int main (){
    return 0;
}

Run Code Online (Sandbox Code Playgroud)

然而,较新的编译器版本不会发生这种情况。请在https://godbolt.org/z/KWeb8WTxz上找到 GCC( 10.x11.x )和 Clang(5.x、6.x)的矩阵来演示差异。

我的问题有两个部分:

  1. 为什么在最近的编译器中没有触发这个?
  2. 是否可以在最新版本的 Clang 或 GCC 中启用旧行为?

Bri*_*ian 60

从 C++11 开始,全局级别的额外分号;(也称为空声明s )是有效的。我相信这对于编写宏有时很有用。

因此,GCC 11 删除了在使用时或稍后使用时-pedantic的额外诊断。看:;-std=c++11

您可以使用早于 C++11 的 C++ 标准来恢复旧行为。如果您通过了,GCC 11 和 clang 6 都会发出旧的诊断信息-std=c++03

另外,GCC 和 Clang 的最新版本都支持警告选项,-Wextra-semi该选项专门警告多余的分号。感谢 HolyBlackCat 提到这一点。

  • @jerin,你可以有一个类似“IF_DEBUG”宏的东西,它可以删除调试版本之外的代码。然后,“IF_DEBUG(int counter = 0);”声明一个仅调试全局变量。当然,您可以将分号放在宏参数列表中,但这可能会扰乱 clang-format 的自动格式化,并且大多数开发人员更喜欢在函数式宏后面加上分号。在非调试版本中,该宏将扩展为空,并且您将得到一个*空声明*。 (9认同)
  • @PlasmaHH 我遇到了 -Wpedantic 在 CI 上的 CentOS 系统中被激活(这个系统构建了许多linux轮子),而我无法在本地触发它(我有较新的编译器)。通过 CI 解决这个问题变得很麻烦,所以想知道幕后发生了什么以及可能性。谷歌搜索并没有给我太多的帮助,因此有一个问题。 (9认同)
  • @HolyBlackCat你不能在命名空间范围内这样做 (3认同)
  • @jerin我想知道的是为什么你这么关心,有一个额外的会有什么坏处?这里和那里? (3认同)
  • @Caleth 在命名空间范围内,您可以执行 `static_assert(true)` 来使用 `;`。这也适用于函数范围...... (2认同)