标量初始化代码中的过量元素使用gcc而不是g ++进行编译 [英] Excess elements in scalar initializer code compiles with gcc but not g++

查看:926
本文介绍了标量初始化代码中的过量元素使用gcc而不是g ++进行编译的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只是好奇为什么这个代码(显然是错误的)使用gcc它编译,但是使用g ++它不是相同的代码。

  int main()
{
char * foo = {bar,fred,bob};

return 0;
}

gcc给出此警告,但仍会编译并生成二进制:


gcc -ox xc



xc: main':xc:3:5:warning:excess
标量初始化器中的元素[默认启用] xc:3:5:warning:
xc:3:5:warning:
标量初始化器中的多余元素[默认启用] xc:3:5:
警告: >

ls -lx



-rwxr-xr-x 1 overdrive overdrive 6593 7月28日21:51 x


g ++提供此错误,没有任何二进制输出:


g ++ -oy y.cpp



y.cpp:在函数'int main )':
y.cpp:3:38:error:标量对象'foo'在初始化器中需要一个元素



ls -ly



ls:无法访问y:没有此类文件或目录


gcc和g ++版本我使用的是:


g ++ --version

g ++(Debian 4.7.2-5)4.7.2
版权所有(C)2012自由软件基金会,
这是免费软件;请参阅复制条件的来源。有NO
保修;甚至不适用于适销性或特定用途的适用性。


有没有什么好的理由为什么这样编译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 ()调用第二个重载,因为第一个重载有一个替换错误。



考虑到这一点,实现面临两个选项:一致拒绝多余的初始化者,或者他们可以仔细确定标准要求它们被拒绝的上下文,并在实施过程中可以继续允许它们。 GCC和clang开发人员选择一致拒绝它们,这显然更容易实现。



C没有任何这样的工具,在编译时确定表达式的有效性,所以对于C,没有办法使这样的扩展导致有效的程序被拒绝。


Just curious why this code (that it is obviously wrong) using gcc it compiles, however the same code using the g++ it does not.

int main()
{
    char *foo = {"bar", "fred", "bob"};

    return 0;
}

gcc gives this warning but still compiles and generates the binary:

% gcc -o x x.c

x.c: In function ‘main’: x.c:3:5: warning: excess elements in scalar initializer [enabled by default] x.c:3:5: warning: (near initialization for ‘foo’) [enabled by default] x.c:3:5: warning: excess elements in scalar initializer [enabled by default] x.c:3:5: warning: (near initialization for ‘foo’) [enabled by default]

% ls -l x

-rwxr-xr-x 1 overdrive overdrive 6593 Jul 28 21:51 x

g++ gives this error and no any binary as an output:

% g++ -o y y.cpp

y.cpp: In function ‘int main()’: y.cpp:3:38: error: scalar object ‘foo’ requires one element in initializer

% ls -l y

ls: cannot access y: No such file or directory

gcc and g++ version I am using is:

% g++ --version
g++ (Debian 4.7.2-5) 4.7.2 Copyright (C) 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Is there any good reason why this compiles in gcc and not in g++? or it is clearly a bug?

解决方案

Yes, there is a good reason for making it a hard error in C++, even on implementations that historically accepted in C:

template <typename T, int = sizeof(T{1,2,3,4})>
void f();

template <typename T>
void f(...) { }

int main() { f<int>(); }

This is a valid C++ program. A compiler must not reject this with a complaint about an ambiguous call or a linker error complaining that the first overload is undefined: the C++ standard requires f<int>() to call the second overload, because the first overload has a substitution error.

With this in mind, implementations are faced with two options: they can either consistently reject excess initialisers, or they can carefully determine in which contexts the standard requires them to be rejected, and in which contexts the implementation can continue to allow them. The GCC and clang developers have opted to consistently reject them, which is significantly easier to implement.

C does not have any such facilities that determine expression validity at compile-time, so for C there is no way for such an extension to cause valid programs to be rejected.

这篇关于标量初始化代码中的过量元素使用gcc而不是g ++进行编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆