标量初始化器代码中的多余元素可以用gcc编译,但不能用g++
Excess elements in scalar initializer code compiles with gcc but not g++
只是好奇为什么这段代码(这显然是错误的)可以用gcc编译,而同样的代码使用g++却不能。
int main()
{
char *foo = {"bar", "fred", "bob"};
return 0;
}
gcc给出这个警告,但仍然编译并生成二进制文件:
% gcc -o x.c
x.c: In function ' main ': x.c:3:5: warning:过量标量初始化器中的元素[默认启用]x.c:3:5: warning:(接近' foo '的初始化)[默认启用]x.c:3:5: warning:标量初始化器中的多余元素[默认启用]警告:(接近初始化' foo ')[默认启用]
% ls -l x
-rwxr-xr-x 1 overdrive overdrive 6593七月28日21:51 x
g++给出了这个错误,并且没有任何二进制文件作为输出:
% g++ - 0 y.cpp
y.p p: In function ' int main() ':y.p:3:38:错误:标量对象' foo '在初始化式
中需要一个元素% ls -l y
ls: cannot access y: No such file or directory
gcc和我使用的g++版本是:
% g++——version
g++ (Debian 4.7.2-5版权所有2012自由软件基金会,Inc。这是自由软件;有关复制条件,请参阅源代码。没有保修;即使不是为了适销性或适合于特定目的。
为什么在gcc中编译而不是在g++中编译?或者它显然是一个bug?
是的,有一个很好的理由使它成为c++中的硬错误,即使是在历史上被接受的C实现中:
template <typename T, int = sizeof(T{1,2,3,4})>
void f();
template <typename T>
void f(...) { }
int main() { f<int>(); }
这是一个有效的c++程序。编译器一定不能拒绝这一点,并抱怨有一个不明确的调用,或者抱怨第一个重载没有定义的链接器错误:c++标准要求f<int>()
调用第二个重载,因为第一个重载有替换错误。
考虑到这一点,实现面临两个选择:它们可以始终拒绝过多的初始化项,或者它们可以仔细确定在哪些上下文中标准要求拒绝它们,以及在哪些上下文中实现可以继续允许它们。GCC和clang开发人员一直选择拒绝它们,这明显更容易实现。
C没有任何在编译时确定表达式有效性的工具,因此对于C来说,这样的扩展没有办法导致有效的程序被拒绝。
根据C 2011标准
标量的初始化式必须是单个表达式(可选)用大括号括起来
动词shall表示编译器将发出诊断消息,:)
所以这是编译器的一个特性或错误:)
根据C标准
符合要求的实施应产生至少一项诊断消息(以实现定义的方式标识)预处理翻译单元或翻译单元包含一个违反任何语法规则或约束,即使行为是也显式指定为未定义或实现定义的
- 为什么 gcc 编译这个而 msvc 没有
- 错误:使用 clang 没有可行的重载,使用 GCC 编译
- 带有自动参数的函数使用 GCC 编译,但不使用 Visual C++ 编译
- 使用 MINGW gcc 编译时,不会为 std::string 调用重载的新运算符
- Steam 回调在 Linux / GCC 编译期间触发警告
- 在其他容器中使用 boost::container::static_vector 时,GCC 编译错误"将'const s'绑定到类型's&'的引用丢弃限定符"
- 如何使用 GCC 编译指示启用选项 '-Werror'?
- 如何实现使用 gcc-4.4 编译的大向量初始化?
- 关于这个在 Linux 上使用 gcc 编译的程序中的 vtable,nm 告诉我什么?
- 使用 TDM GCC 5.1.0 编译 PDCurses36 时出错
- 为什么这段代码无法使用 gcc 4.8.5 编译,而使用 clang 编译正常
- 使用 std::addressof 时出现 GCC 7 编译错误
- 在类模板上使用 arm gcc 编译期间的隔离错误
- 使用 GCC 编译C++时如何包含 C11 标头?
- 类数据成员指针的非类型模板参数包无法使用 gcc 编译
- 是否可以使用 GCC 编译具有特定编译器标志的代码文件的一部分?
- 将 cctype 函数分配给 std::function,gcc 编译错误
- GCC 编译时出现警告:未知转义序列:"\040"
- 为什么以下代码不使用GCC编译,而是用Clang编译罚款
- GCC编译器,为较低版本的GCC编译应用程序