Bor*_*aso 3 c c++ gcc compiler-errors g++
只是好奇为什么这个代码(显然是错误的)使用gcc编译,但是使用g ++的相同代码却没有.
int main()
{
char *foo = {"bar", "fred", "bob"};
return 0;
}
Run Code Online (Sandbox Code Playgroud)
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 ++ --version
g ++(Debian 4.7.2-5)4.7.2版权所有(C)2012 Free Software Foundation,Inc.这是免费软件; 查看复制条件的来源.没有保修; 甚至不适用于适销性或特定用途的适用性.
有没有什么好的理由为什么这个用gcc编译而不是用g ++编译?或者它显然是一个错误?
小智 8
是的,有一个很好的理由使它成为C++中的一个硬错误,即使在历史上在C中接受的实现:
template <typename T, int = sizeof(T{1,2,3,4})>
void f();
template <typename T>
void f(...) { }
int main() { f<int>(); }
Run Code Online (Sandbox Code Playgroud)
这是一个有效的C++程序.编译器不能拒绝这一点,抱怨模糊调用或链接器错误抱怨第一个重载未定义:C++标准需要f<int>()调用第二个重载,因为第一个重载有一个替换错误.
考虑到这一点,实现面临两个选择:它们可以始终拒绝多余的初始化程序,或者它们可以仔细确定标准要求拒绝它们的上下文,以及实现可以继续允许它们的上下文.GCC和clang开发人员选择不断拒绝它们,这更容易实现.
C没有任何在编译时确定表达式有效性的工具,因此对于C,这种扩展无法使有效程序被拒绝.