警告:'auto' 类型说明符是 C++11 扩展

Posted

技术标签:

【中文标题】警告:\'auto\' 类型说明符是 C++11 扩展【英文标题】:warning: 'auto' type specifier is a C++11 extension警告:'auto' 类型说明符是 C++11 扩展 【发布时间】:2021-07-11 21:05:06 【问题描述】:

我有一个非常简单的 C++ 代码语句auto a = 12;

当我在 Linux 中使用 -std=c++98 选项使用 g++ 编译它时,我得到了预期的错误

error: ‘a’ does not name a type

但是当我在 MacOS 中使用相同的选项编译相同的代码时,我只会收到一个警告,但代码编译得很好。

warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]

但是-std=c++98 的全部意义不在于按照 C++ 98 标准编译代码吗?因此,即使 auto 是 C++11 扩展,警告也会告诉我要为您编译它?

有没有强制使用c++98(或其他标准)的选项?

g++ --version 打印 Apple clang version 12.0.0 (clang-1200.0.32.29) 顺便说一句,这是另一件奇怪的事情。所以实际上是clang。

这就像问firefox --version 并得到chrome 87.0.4280.163

【问题讨论】:

编译器是对的。直到 C++11 标准才添加自动类型推导。它在(第一个)C++98 标准发布 13 年后问世。如果您想使用较早的标准,则不能使用后来的标准中引入的东西。为什么要继续使用(现在古老)C++98 标准?你知道我们符合 C++20 标准吗?标准的每次更新都让 C++ 变得更好。 @Someprogrammerdude:C98 也有 auto,但它意味着别的东西。如果它是在 C98 模式下编译,它确实应该使用 auto 的 C98 解释。 @Someprogrammerdude 感谢您建议我使用最新的语言标准,但我的问题与您的答案没有任何关系。是的,我知道有一个 C++20 标准并广泛使用它。我也知道 C++23 大概会有什么特性。但这并不意味着人们永远不应询问有关旧标准的问题。 @Yksisarvinen:除了 ancient 版本的 C 只会假设随机的 auto 变量都是 int,并且一些编译器将其带到 C98 中:(跨度> @MooingDuck 我相信旧版本的 GCC 和其他一些版本甚至允许这些设置,例如默认将所有变量设为静态并假设 K&R 样式默认为 int。我认为,Wacom C 做到了。 【参考方案1】:

您可能正在寻找-pedantic-pedantic-errors,引用man g++:

-迂腐

发出严格的 ISO C 和 ISO C++ 要求的所有警告;拒绝所有使用禁止扩展的程序,以及其他一些程序 不遵循 ISO C 和 ISO C++ 的程序。对于 ISO C,如下 使用的任何 -std 选项指定的 ISO C 标准的版本。

注意:这并不是检查严格标准一致性的功能(请参阅手册页中的其余说明)

【讨论】:

使用-std=c++98 -pedantic,clang 仍然会打印非致命警告。看我的回答。【参考方案2】:

在 MacOS 上,您使用的是 clang,而不是 gcc。 (如果我没记错的话,MacOS 分别提供了“gcc”和“g++”作为“clang”和“clang++”的符号链接,因此假定 gcc 的脚本不会中断。)

这两个编译器只是处理这种情况的方式不同。

是的,符合 1998 ISO C 标准的编译器,正如 gcc 和 clang 尝试使用 -std=c++98 所做的那样,必须诊断该行。

就标准而言,非致命警告是有效的诊断。该标准不要求拒绝无效程序(除非它包含#error 指令)。

如果您想严格执行 C++98 规则并拒绝违反这些规则的代码,请使用 -std=c++98 -pedantic-errors(使用 gcc 或 clang)。

【讨论】:

感谢工作。即使我认为在没有其他选项的情况下仅打印错误会更直观。如果我说“使用 98 标准编译此代码”,则意味着除非给出其他选项,否则请使用 98 标准编译代码。 @AshotKhachatryan 这正是它所做的。 1998 年的 C++ 标准要求一个符合要求的实现来为包含违反任何“可诊断规则”的程序“发出至少一个诊断消息”。它不需要实现来拒绝这样的程序。通过打印该非致命警告,clang 满足了标准的要求。通过指定-std=c++98 -pedantic-errors,您可以将其配置为超出标准要求并拒绝出现错误的程序。 明确地说,我个人更希望标准要求拒绝违反语法或语义规则的程序,但至少大多数编译器都有一个选项可以让他们这样做。 @KeithThompson 从技术上讲,这并不违反 C++98,只是意味着不同的东西。 auto 表示 pre-ISO C 和 ISO C++98 中的自动变量。它与函数本地 staticregister 相反。您在 auto int a = 12 之后输入了 at 类型,但一些许可设置可能允许默认 int。为了与旧代码兼容。 @Swift-FridayPie auto 关键字在 C++98 中确实有不同的含义,但 auto a = 12; 在 C++98 中是违反规则的,因为没有类型名称。 auto int a = 12 在 C++98 中是合法的,但在 C++11 中出现错误(因为 auto 的旧含义已被删除,而新含义它指定了两种类型——即使它们碰巧发生也属于违规行为是同一类型)。

以上是关于警告:'auto' 类型说明符是 C++11 扩展的主要内容,如果未能解决你的问题,请参考以下文章

C#的未来:简化参数空值验证

[C/C++]_[初级]_[关于编译时出现有符号-无符号不匹配的警告-sizeof使用注意事项]

[C/C++]_[初级]_[关于编译时出现有符号-无符号不匹配的警告-sizeof使用注意事项]

什么是 C++11 扩展 [-Wc++11-extensions]

gcc 的扩展初始化程序列出警告

[C/C++]_[初级]_[关于编译时出现有符号-无符号不匹配的警告-sizeof使用注意事项]