简体   繁体   中英

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.

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

    return 0;
}

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

% 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]

% ls -lx

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

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

% g++ -oy y.cpp

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

% ls -ly

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.

According to the C 2011 Standard

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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