Bug 43453 - Initialization of char array with string literal fails in mem-initializer
Summary: Initialization of char array with string literal fails in mem-initializer
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.4.3
: P3 normal
Target Milestone: 5.0
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2010-03-20 03:06 UTC by Johannes Schaub
Modified: 2014-06-05 20:56 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 4.7.0
Last reconfirmed: 2012-01-28 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Johannes Schaub 2010-03-20 03:06:23 UTC
Fails to compile, but should work:

struct A { 
  char x[4]; 
  A():x("bug") { } 
};

Error i get is:

"main.cpp:3: error: array used as initializer"
Comment 1 Christopher Yeleighton 2010-08-27 18:06:28 UTC
(In reply to comment #0)
> Fails to compile, but should work:
> 
> struct A { 
>   char x[4]; 
>   A():x("bug") { } 
> };
> 
> Error i get is:
> 
> "main.cpp:3: error: array used as initializer"
> 

Why do you think it should work?  
For example, the following equivalent code is invalid as well:

char x [4] ("bug");
Comment 2 Johannes Schaub 2010-08-28 14:39:58 UTC
(In reply to comment #1)
> (In reply to comment #0)
> > Fails to compile, but should work:
> > 
> > struct A { 
> >   char x[4]; 
> >   A():x("bug") { } 
> > };
> > 
> > Error i get is:
> > 
> > "main.cpp:3: error: array used as initializer"
> > 
> 
> Why do you think it should work?  
> For example, the following equivalent code is invalid as well:
> 
> char x [4] ("bug");
> 

This code is equivalent and is valid. At least, I don't see the Standard forbidding it. GCC is the only compiler I tested (comeau/edg, clang) that rejects it.
Comment 3 Johannes Schaub 2010-10-30 09:41:36 UTC
(In reply to comment #2)
> (In reply to comment #1)
> > (In reply to comment #0)
> > > Fails to compile, but should work:
> > > 
> > > struct A { 
> > >   char x[4]; 
> > >   A():x("bug") { } 
> > > };
> > > 
> > > Error i get is:
> > > 
> > > "main.cpp:3: error: array used as initializer"
> > > 
> > 
> > Why do you think it should work?  
> > For example, the following equivalent code is invalid as well:
> > 
> > char x [4] ("bug");
> > 
> 
> This code is equivalent and is valid. At least, I don't see the Standard
> forbidding it. GCC is the only compiler I tested (comeau/edg, clang) that
> rejects it.

I'm not actually sure anymore about the validity of this code. One can make a point about the initializer not being a mere string literal.

At least the draft n3126 makes a difference of this, in that an initializer like "({a, b, c})" is not regarded as a braced-init-list, but rather as a parenthesized expression-list where the initializer list is handed as one argument. So I'm unsure whether an initializer like `("foo")` should be regarded as a string literal or not.

I think I will send an issue report about this.
Comment 4 Johannes Schaub 2011-05-14 16:18:58 UTC
(In reply to comment #3)
> (In reply to comment #2)
> > (In reply to comment #1)
> > > (In reply to comment #0)
> > > > Fails to compile, but should work:
> > > > 
> > > > struct A { 
> > > >   char x[4]; 
> > > >   A():x("bug") { } 
> > > > };
> > > > 
> > > > Error i get is:
> > > > 
> > > > "main.cpp:3: error: array used as initializer"
> > > > 
> > > 
> > > Why do you think it should work?  
> > > For example, the following equivalent code is invalid as well:
> > > 
> > > char x [4] ("bug");
> > > 
> > 
> > This code is equivalent and is valid. At least, I don't see the Standard
> > forbidding it. GCC is the only compiler I tested (comeau/edg, clang) that
> > rejects it.
> 
> I'm not actually sure anymore about the validity of this code. One can make a
> point about the initializer not being a mere string literal.
> 
> At least the draft n3126 makes a difference of this, in that an initializer
> like "({a, b, c})" is not regarded as a braced-init-list, but rather as a
> parenthesized expression-list where the initializer list is handed as one
> argument. So I'm unsure whether an initializer like `("foo")` should be
> regarded as a string literal or not.
> 
> I think I will send an issue report about this.

Subsequent discussion with Jason showed that this is covered by 8.5p13:

   The form of initialization (using parentheses or =) is generally 
   insignificant, but does matter when the initializer or the entity 
   being initialized has a class type;

As this is an array, the text in the Standard in general has to be interpreted that a "=" or a "(..)" initializer are equivalent, unless otherwise stated. 

So this is indeed a GCC bug (both that it rejects the member initialization and the parenthesized non-member initialization).
Comment 5 Andrew Pinski 2012-01-28 05:43:59 UTC
Confirmed.
Comment 6 Paolo Carlini 2014-05-26 10:37:51 UTC
Mine.
Comment 7 paolo@gcc.gnu.org 2014-06-04 22:31:11 UTC
Author: paolo
Date: Wed Jun  4 22:30:39 2014
New Revision: 211248

URL: http://gcc.gnu.org/viewcvs?rev=211248&root=gcc&view=rev
Log:
/cp
2014-06-04  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/43453
	* typeck.c (cp_build_modify_expr): Handle array of characters
	initialized by a string literal.
	* decl.c (check_initializer): Handle parenthesized string literal
	as initializer.
	* typeck2.c (store_init_value): Remove redundant check.

/testsuite
2014-06-04  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/43453
	* g++.dg/init/pr43453.C: New.

Added:
    trunk/gcc/testsuite/g++.dg/init/pr43453.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/decl.c
    trunk/gcc/cp/typeck.c
    trunk/gcc/cp/typeck2.c
    trunk/gcc/testsuite/ChangeLog
Comment 8 Paolo Carlini 2014-06-04 22:32:01 UTC
Fixed for 4.10.0.
Comment 9 Jason Merrill 2014-06-05 20:56:15 UTC
Author: jason
Date: Thu Jun  5 20:55:44 2014
New Revision: 211290

URL: http://gcc.gnu.org/viewcvs?rev=211290&root=gcc&view=rev
Log:
	PR c++/43453
	* decl.c (check_initializer): Collapse a TREE_LIST here.
	* typeck2.c (store_init_value): Not here.

Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/decl.c
    trunk/gcc/cp/typeck2.c