[英]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 -ox xc
xc:在函数'main'中:xc:3:5:警告:标量初始化程序中的多余元素[默认启用] xc:3:5:警告:(接近初始化'foo')[默认启用] xc:3 :5:警告:标量初始化程序中的多余元素[默认启用] xc:3:5:警告:(接近初始化'foo')[默认启用]
% ls -lx
-rwxr-xr-x 1 overdrive overdrive 6593 Jul 28 21:51 x
g ++给出了这个错误,没有任何二进制文件作为输出:
% g ++ -oy y.cpp
y.cpp:在函数'int main()'中:y.cpp:3:38:错误:标量对象'foo'在初始化程序中需要一个元素
% ls -ly
ls:无法访问y:没有这样的文件或目录
我使用的gcc和g ++版本是:
% g ++ - 版本
g ++(Debian 4.7.2-5)4.7.2版权所有(C)2012 Free Software Foundation,Inc。这是免费软件; 查看复制条件的来源。 没有保修; 甚至不适用于适销性或特定用途的适用性。
有没有什么好的理由为什么这个用gcc编译而不是用g ++编译? 或者它显然是一个错误?
是的,有一个很好的理由使它成为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标准
标量的初始值设定项应为单个表达式,可选择用大括号括起来
动词应表示编译器应发出诊断消息,:)
所以它是编译器的一个特性或错误。:)
根据C标准
1如果预处理转换单元或转换单元包含违反任何语法规则或约束的情况,则符合要求的实现应生成至少一条诊断消息(以实现定义的方式标识),即使该行为也明确指定为未定义或实现-defined
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.