Bug 60009 - g++ allows copy-initialization of an array of class type from a non-braced string literal
Summary: g++ allows copy-initialization of an array of class type from a non-braced st...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.8.1
: P3 normal
Target Milestone: 7.0
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid
Depends on:
Blocks:
 
Reported: 2014-01-31 14:52 UTC by Ed Catmur
Modified: 2021-10-06 18:42 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 4.8.2, 4.9.1, 5.0
Last reconfirmed: 2014-12-14 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ed Catmur 2014-01-31 14:52:54 UTC
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.
Comment 1 TC 2014-06-25 04:21:26 UTC
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.
Comment 2 Ville Voutilainen 2014-12-14 14:16:52 UTC
Clang rejects the code.
Comment 3 Andrew Pinski 2021-07-27 21:46:46 UTC
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.
Comment 4 Patrick Palka 2021-10-06 18:42:34 UTC
(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