简体   繁体   English

标量初始化程序代码中的多余元素使用gcc但不使用g ++进行编译

[英]Excess elements in scalar initializer code compiles with gcc but not g++

Just curious why this code (that it is obviously wrong) using gcc it compiles, however the same code using the g++ it does not. 只是好奇为什么这个代码(显然是错误的)使用gcc编译,但是使用g ++的相同代码却没有。

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

    return 0;
}

gcc gives this warning but still compiles and generates the binary: gcc提供此警告但仍编译并生成二进制文件:

% gcc -ox xc gcc -ox xc

xc: In function 'main': xc:3:5: warning: excess elements in scalar initializer [enabled by default] xc:3:5: warning: (near initialization for 'foo') [enabled by default] xc:3:5: warning: excess elements in scalar initializer [enabled by default] xc:3:5: warning: (near initialization for 'foo') [enabled by default] xc:在函数'main'中:xc:3:5:警告:标量初始化程序中的多余元素[默认启用] xc:3:5:警告:(接近初始化'foo')[默认启用] xc:3 :5:警告:标量初始化程序中的多余元素[默认启用] xc:3:5:警告:(接近初始化'foo')[默认启用]

% ls -lx ls -lx

-rwxr-xr-x 1 overdrive overdrive 6593 Jul 28 21:51 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 ++给出了这个错误,没有任何二进制文件作为输出:

% g++ -oy y.cpp g ++ -oy y.cpp

y.cpp: In function 'int main()': y.cpp:3:38: error: scalar object 'foo' requires one element in initializer y.cpp:在函数'int main()'中:y.cpp:3:38:错误:标量对象'foo'在初始化程序中需要一个元素

% ls -ly ls -ly

ls: cannot access y: No such file or directory ls:无法访问y:没有这样的文件或目录

gcc and g++ version I am using is: 我使用的gcc和g ++版本是:

% g++ --version g ++ - 版本
g++ (Debian 4.7.2-5) 4.7.2 Copyright (C) 2012 Free Software Foundation, Inc. This is free software; g ++(Debian 4.7.2-5)4.7.2版权所有(C)2012 Free Software Foundation,Inc。这是免费软件; 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++? 有没有什么好的理由为什么这个用gcc编译而不是用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: 是的,有一个很好的理由使它成为C ++中的一个硬错误,即使在历史上在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. 这是一个有效的C ++程序。 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. 编译器不能拒绝这一点,抱怨模糊调用或链接器错误抱怨第一个重载未定义:C ++标准要求f<int>()调用第二个重载,因为第一个重载有一个替换错误。

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. GCC和clang开发人员选择不断拒绝它们,这更容易实现。

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. C没有任何在编译时确定表达式有效性的工具,因此对于C,这种扩展无法使有效程序被拒绝。

According to the C 2011 Standard 根据C 2011标准

The initializer for a scalar shall be a single expression, optionally enclosed in braces 标量的初始值设定项应为单个表达式,可选择用大括号括起来

The verb shall means that the compiler shall issue a diagnostic message,:) 动词应表示编译器应发出诊断消息,:)

So it is a feature or a bug of the compiler.:) 所以它是编译器的一个特性或错误。:)

According to the C Standard 根据C标准

1 A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined 1如果预处理转换单元或转换单元包含违反任何语法规则或约束的情况,则符合要求的实现应生成至少一条诊断消息(以实现定义的方式标识),即使该行为也明确指定为未定义或实现-defined

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM