The following code should be rejected, but is accepted by g++ 4.8.1, in both C++03 and C++11 mode: struct s { s(const char *); } a[] = ""; It is rejected by clang++ and MSVC. Credit: http://stackoverflow.com/questions/21481462/what-does-this-code-mean-and-why-does-it-work List-initialization is correctly allowed in the braced-init-list case (a[]{""}), and correctly disallowed in the parenthesized case (a[]("")). Giving the array extent (a[2] = "") does not appear to make any difference. It looks like the extent of the array is being taken from the length of the string literal (including terminator), with some amusing results: #include <string> #include <iostream> int main() { std::string a[] = "hello"; for (int i = 0; i < sizeof(a)/sizeof(a[0]); ++i) std::cout << a[i] << '\n'; } outputs: hello hello hello hello hello hello (6, count 'em). If an array extent is provided (e.g. std::string a[10] = "hello"), then the string literal will be used to initialize each element.
http://stackoverflow.com/questions/24378882/weird-gcc-array-initialization-behavior appears to be related. Minimal example: struct A { A() { } }; int main() { A a[10] = A(); } Compiles with GCC 4.6, 4.7, 4.8 and 4.9, in both C++98 and C++11 modes, even though it shouldn't. However, struct A { }; int main() { A a[10] = A(); } does not compile in any of the GCC versions tested. struct A { A() = default; }; int main() { A a[10] = A(); } Compiles with GCC 4.9 in C++11 mode; does not compile with 4.6-4.8 in C++ 11 mode, however.
Clang rejects the code.
Fixed in GCC 7, I cannot figure out which revision fixed it though. Note r8-7514 fixes the error message though where in GCC 7 would print out some error messages dealing with no matching of constructors.
(In reply to Andrew Pinski from comment #3) > Fixed in GCC 7, I cannot figure out which revision fixed it though. > > Note r8-7514 fixes the error message though where in GCC 7 would print out > some error messages dealing with no matching of constructors. Fixed by r7-7236 FWIW