【问题标题】:g++ is not producing an error when it should, e.g. "error: variable length array of non-POD element type"g++ 在应该的时候没有产生错误,例如“错误:非 POD 元素类型的可变长度数组”
【发布时间】:2014-07-15 08:27:48
【问题描述】:

在我的 C++ 程序中,有时我会这样做:

std::cin >> my_int;
my_class my_array[my_int];

当我在 OSX 上使用 g++ 编译它时,我得到:

错误:非 POD 元素类型的可变长度数组

正如预期的那样。但是,当我在 Ubuntu 上编译它时,我没有收到任何错误。在这两种情况下,我都没有任何选项进行编译。

供参考,g++ --version 在 OSX 输出上:

Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/c++/4.2.1
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.3.0
Thread model: posix

在 Ubuntu 上输出:

g++ (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3
Copyright (C) 2009 Free Software Foundation, Inc.

关于为什么我没有收到错误的任何想法?

P.S.:我试过 apt-get updateapt-get install g++ 但由于某种原因,我得到的回应是我有最新版本,如果我没记错的话是 4.9.0,我没有...

【问题讨论】:

  • 如你所见,你的OS X系统上的“g++”实际上是clang。
  • 正确,但是g++ 没有抛出错误的原因仍然是个谜。
  • 不需要编译器来报告无效 C++ 代码的错误。他们都被允许实现“语言扩展”,从可能无法编译的代码中生成工作二进制文件。 简而言之:您应该期望正确 C++ 能够编译,但您应该不期望 不正确 C++。
  • @DrewDormann:每个符合 C++ 编译器都必须为任何违反某些规则的程序发出至少一条诊断消息。默认情况下,g++ 不是符合标准的 C++ 编译器。
  • @KeithThompson 非常有趣!谢谢你分享。我已经过了我的编辑窗口,所以在上面和下面 +1...

标签: c++ macos ubuntu g++


【解决方案1】:

任何符合 ISO C++ 的编译器都需要为该错误发出诊断。更准确地说,对于任何违反 ISO 标准中特定规则的程序,都需要发出至少一条诊断消息。

g++ 默认不是完全符合 C++ 的编译器。

要使其(尝试)符合 C++ 标准,请使用 -pedantic 选项,最好与指定 C++ 标准版本的选项一起使用。

例如,当我编译类似于你的程序的东西时,g++ 默认情况下不会给出任何警告——但是当我用它编译时

g++ -pedantic

g++ -std=c++11 -pedantic`

我明白了:

c.cpp: In function ‘int main()’:
c.cpp:5:24: warning: ISO C++ forbids variable length array ‘my_array’ [-Wvla]

有关 g++ 符合 C++ 标准的更多信息,请参阅手册;输入info g++ 并阅读"Standards""C++ Extensions" 部分(链接指向手册的在线版本)。

【讨论】:

    【解决方案2】:

    GCC 支持一些非标准扩展,其中之一是某些非 POD 类型的可变长度数组。

    另一方面,Clang 力求更加符合标准。

    来自Clang compatibility FAQ

    GCC 和 C99 允许在运行时确定数组的大小。这个 标准 C++ 中不允许扩展。但是,Clang 支持 这种可变长度数组在非常有限的情况下 与 GNU C 和 C99 程序的兼容性:

    • 变长数组的元素类型必须是POD(“plain old data”)类型,这意味着它不能有任何用户声明的 构造函数或析构函数、任何基类或 非 POD 类型。所有 C 类型都是 POD 类型。
    • 变长数组不能用作非类型模板参数的类型。

    正如@Brian 所指出的,您在您的 OSX 机器上使用 Clang(毫不奇怪,Apple 创建了 LLVM)和在您的 Ubuntu 机器上使用 GCC。

    【讨论】:

    • gcc/g++ 如果您使用-pedantic 选项很好地询问它,它确实会努力符合标准。见my answer
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-30
    • 1970-01-01
    • 2012-03-21
    • 2023-03-06
    • 2020-09-01
    • 1970-01-01
    相关资源
    最近更新 更多