7

Very simple question. Is this valid C++11?

struct Foo {
    int bar = 1;
    int baz = bar;
};

GCC (4.7.2) and Clang (3.1) both accept it with the pedantic settings:

-std=c++11 -Wall -W -pedantic

Intel C++ (13.0.1.117) does not. It barks at int baz = bar; with:

error: a nonstatic member reference must be relative to a specific object

Who is right?

In case you wonder, I use this for code like this, where it brings initialization code closer together, rather than moving the last line into the constructor:

uint8_t colorR = -1;
uint8_t colorG = -1;
uint8_t colorB = -1;
uint8_t colorA = -1;
GLubyte RGBAVec[4] = {colorR, colorG, colorB, colorA};
ildjarn
  • 62,044
  • 9
  • 127
  • 211
Nikos C.
  • 50,738
  • 9
  • 71
  • 96

1 Answers1

3

5.1p12 An id-expression that denotes a non-static data member or non-static member function of a class can only be used:

  • as part of a class member access (5.2.5) in which the object expression refers to the member’s class or a class derived from that class, or
  • to form a pointer to member (5.3.1), or
  • in a mem-initializer for a constructor for that class or for a class derived from that class (12.6.2), or
  • in a brace-or-equal-initializer for a non-static data member of that class or of a class derived from that class (12.6.2), or
  • if that id-expression denotes a non-static data member and it appears in an unevaluated operand.

So yes, this :

struct Foo {
  int bar = 1;
  int baz = bar;
};

is valid C++11.

But be carefull about order because :

12.6.2p10 In a non-delegating constructor, initialization proceeds in the following order:

  • First, and only for the constructor of the most derived class (1.8), virtual base classes are initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where “left-to-right” is the order of appearance of the base classes in the derived class base-specifier-list.
  • Then, direct base classes are initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers).
  • Then, non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).
  • Finally, the compound-statement of the constructor body is executed

So as specified in the Non-static data member initializers proposal (Problem 3) :

A third issue is that class-scope lookup could turn a compile-time error into a run-time error:

struct S {
    int i = j; // ill-formed without forward lookup, undefined behavior with
    int j = 3;
};

(Unless caught by the compiler, i might be intialized with the undefined value of j.)

Drax
  • 12,682
  • 7
  • 45
  • 85
  • Thanks. That looks definitive. Though what is meant with "or of a class derived from that class"? How is it possible to initialize a member with a member of a derived class? The derived class has not been declared yet, so it's not possible to access it. – Nikos C. Dec 14 '12 at 16:55
  • @Nikos C. "or of a class derived from that class" refers to "a brace-or-equal-initializer" which means that the initializer is the one being in the dervied class. Basically i think it means you can initialize non static data members with non static data member of your parent classes. It is the other way around the one you understood it, which makes much more sense :) – Drax Dec 14 '12 at 17:10