Bug 65815 - brace elision doesn't work in NSDMI
Summary: brace elision doesn't work in NSDMI
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.9.2
: P3 normal
Target Milestone: 6.0
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
: 88661 (view as bug list)
Depends on:
Blocks: NSDMI
  Show dependency treegraph
 
Reported: 2015-04-20 15:16 UTC by andras.aszodi
Modified: 2019-01-02 14:17 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2015-04-20 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description andras.aszodi 2015-04-20 15:16:16 UTC
On Page 975 of "The C++ Programming Language", 4th edition, Bjarne Stroustrup says:

"An array can be initialized by an initializer list:
array<int,3> a1 = { 1, 2, 3 };"

and Clang (V 3.5) accepts it. However, G++ 4.9.2 thinks this is an error:

"error: array must be initialized with a brace-enclosed initializer
     const std::array<double, 3> _ar0val = {1.0, -1.0, 1.0};"

The ugly fix is:

#ifdef __GNUC__
    const std::array<double, 3> _ar0val{{1.0, -1.0, 1.0}};
#else
    const std::array<double, 3> _ar0val = {1.0, -1.0, 1.0};
#endif

but of course it is still a bug.
Comment 1 Marek Polacek 2015-04-20 15:22:47 UTC
Hm?  This compiles just fine for me:

#include <array>
const std::array<double, 3> q1 = {1.0, -1.0, 1.0};
const std::array<double, 3> q2{{1.0, -1.0, 1.0}};

So can you provide a complete test case?
Comment 2 Jonathan Wakely 2015-04-20 15:31:10 UTC
Works for me, please provide a complete testcase and your exact g++ command.

https://gcc.gnu.org/bugs/
Comment 3 andras.aszodi 2015-04-21 10:35:19 UTC
(In reply to Marek Polacek from comment #1)
> Hm?  This compiles just fine for me:
> 
> #include <array>
> const std::array<double, 3> q1 = {1.0, -1.0, 1.0};
> const std::array<double, 3> q2{{1.0, -1.0, 1.0}};
> 
> So can you provide a complete test case?

Thanks a lot. Yes, this works for me, too:

#include <array>
#include <iostream>

int main(int argc, char *argv[]) {
  std::array<double, 2> a = {1.0, 2.0};
  std::cout << a[0] << ", " << a[1] << std::endl;
}

The problem manifests itself if the array is a member variable in a class and initialised "inline". Details in my new comment below.
Comment 4 Daniel Krügler 2015-04-21 10:46:22 UTC
(In reply to andras.aszodi from comment #3)
> The problem manifests itself if the array is a member variable in a class
> and initialised "inline". Details in my new comment below.

There are no details anywhere. Please keep in mind that a complete code example is generally required for an issue. So, if I understand you correctly, you have the following code in mind:

//------------------------------
#include <array>

struct X 
{
  std::array<double, 3> q1 = {1.0, -1.0, 1.0}; 
};
//------------------------------

?
Comment 5 andras.aszodi 2015-04-21 10:48:05 UTC
If the array is a class member and it is initialized in-class then the "single-brace" syntax gets flagged. Please try the following example:

// ----- file clarrinit.cc --
#include <array>
#include <iostream>

class Fred {
  public:
  const std::array<double, 2>& arr() const { return _a; }

  private:
  std::array<double, 2> _a = {1.0, 2.0}, // error
    _b{3.0, 4.0}, // error
    _c{{5.0, 6.0}}; // OK
};

int main(int argc, char *argv[]) {
  Fred f;
  std::cout << f.arr()[0] << std::endl;
}
// ----

Platform: Raspberry Pi 2, OS is Raspbian (not that it should matter IMO)
Command: `g++-4.9 -g -std=c++11 clarrinit.cc -o clarrinit`
Output: 
error: array must be initialized with a brace-enclosed initializer
   std::array<double, 2> _a = {1.0, 2.0},
                                       ^
clarrinit.cc:9:39: error: too many initializers for ‘std::array<double, 2u>’
clarrinit.cc:10:16: error: array must be initialized with a brace-enclosed initializer
     _b{3.0, 4.0},
                ^
clarrinit.cc:10:16: error: too many initializers for ‘std::array<double, 2u>’
Comment 6 andras.aszodi 2015-04-21 10:48:42 UTC
You were too quick, I was too slow... please re-check :-)

(In reply to Daniel Krügler from comment #4)
> (In reply to andras.aszodi from comment #3)
> > The problem manifests itself if the array is a member variable in a class
> > and initialised "inline". Details in my new comment below.
> 
> There are no details anywhere. Please keep in mind that a complete code
> example is generally required for an issue. So, if I understand you
> correctly, you have the following code in mind:
> 
> //------------------------------
> #include <array>
> 
> struct X 
> {
>   std::array<double, 3> q1 = {1.0, -1.0, 1.0}; 
> };
> //------------------------------
> 
> ?
Comment 7 Jonathan Wakely 2015-04-21 10:56:12 UTC
Reduced:

struct array {
  int data [2];
};

struct X {
  array a = { 1, 2 };
};
Comment 8 Paolo Carlini 2015-05-22 16:22:35 UTC
Mine.
Comment 9 paolo@gcc.gnu.org 2015-06-09 14:59:40 UTC
Author: paolo
Date: Tue Jun  9 14:59:08 2015
New Revision: 224286

URL: https://gcc.gnu.org/viewcvs?rev=224286&root=gcc&view=rev
Log:
/cp
2015-06-09  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/65815
	* typeck2.c (digest_nsdmi_init): On aggregates use reshape_init.
	* init.c (expand_default_init): Likewise.

/testsuite
2015-06-09  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/65815
	* g++.dg/cpp0x/nsdmi-aggr1.C: New.
	* g++.dg/cpp0x/mem-init-aggr1.C: Likewise.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/mem-init-aggr1.C
    trunk/gcc/testsuite/g++.dg/cpp0x/nsdmi-aggr1.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/init.c
    trunk/gcc/cp/typeck2.c
    trunk/gcc/testsuite/ChangeLog
Comment 10 Paolo Carlini 2015-06-09 15:03:44 UTC
Fixed.
Comment 11 Jonathan Wakely 2019-01-02 14:17:05 UTC
*** Bug 88661 has been marked as a duplicate of this bug. ***