3

I am having a hard time trying to figure out why this code seems to work. Shouldn't I get an "array initializer must be an initializer list" error?

#include <iostream>

class B {
public:
  B() { std::cout << "B Constructor " << std::endl ; }
  B(const B&) { std::cout << "B Copy Constructor " << std::endl ; }
  ~B() { std::cout << "B Destructor " << std::endl ; }
} ;

class A {
public:
  A() { std::cout << "A Constructor " << std::endl ; }
  A(const A& other) : bs(other.bs)
        { std::cout << "A Copy Constructor " << std::endl ;}
  ~A() { std::cout << "A Destructor " << std::endl ; }
private:
  B bs[12] ;
};


int main() {
    A a ;
    A b(a) ;
    return 0 ;
}

The output of g++ --version is g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18)

etien
  • 301
  • 1
  • 9
  • 1
    Add a standard flag (`--std=c++0x` or `--std=c++03`), as well as the `-pedantic-errors` flag, and you'll see it's an extension. If that doesn't help, then GCC 4.4.7 has a bug. – StoryTeller - Unslander Monica Jan 17 '18 at 18:36
  • 1
    Very interesting. All version off gcc on [godbolt](https://gcc.godbolt.org/) compile this code while all versions off clang reject it. I suspect this is a gcc bug/extension. Unfortunately using `-pedantic` doesn't change anything with gcc in this case. – NathanOliver Jan 17 '18 at 18:54
  • 1
    Possible dupe with maybe the related bug report in the second answer: https://stackoverflow.com/questions/24378882/weird-gcc-array-initialization-behavior – NathanOliver Jan 17 '18 at 19:05

1 Answers1

4

It is ill-formed, and GCC has a bug. You specify GCC 4.4.7, so I'm going to base this answer on C++11. The meaning of an initializer is determined by [dcl.init]/16:

The semantics of initializers are as follows. The destination type is the type of the object or reference being initialized and the source type is the type of the initializer expression. If the initializer is not a single (possibly parenthesized) expression, the source type is not defined.

  • the initializer is a (non-parenthesized) braced-init-list, the object or reference is list-initialized ([dcl.init.list]).
  • If the destination type is a reference type, see [dcl.init.ref].
  • If the destination type is an array of characters, an array of char16_t, an array of char32_t, or an array of wchar_t, and the initializer is a string literal, see [dcl.init.string].
  • If the initializer is (), the object is value-initialized.
  • Otherwise, if the destination type is an array, the program is ill-formed.
  • [... Continued but irrelevant here ... ]

The bullets must be checked in order to determine the meaning of an initializer for a target type. Since you use (other.bs) as an initializer, and the target type is an array, the only applicable bullet is the one I highlighted. The program is ill-formed.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458