0

A similar question got asked here, but didn't get a proper answer.

Is the following legal?

struct B;

struct A
{
    A(B& b) : b(b) 
    {
    }

    B& b;
};

struct B
{
    B(A& a) : a(a)
    {
    }

    A& a;
};

struct C
{
    C() : a(b), b(a)
    {
    }

    A a;
    B b;
};

I wonder if it falls under 3.8 (6) (C++ 2003)

... before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any lvalue which refers to the original object may be used but only in limited ways. Such an lvalue refers to allocated storage (3.7.3.2), and using the properties of the lvalue which do not depend on its value is well-defined.

Community
  • 1
  • 1
fizzer
  • 13,551
  • 9
  • 39
  • 61
  • Not sure if it's relevant to your question, but it looks to me like that initializer list for `C` will never work right. The order of initialisation is dependent on the order of declaration. – Roger Rowland Jun 19 '13 at 09:38
  • 2
    I think as long as the A and B constructors only memorize references without accessing the referenced objects, they will succeed. I guess this counts as "using the properties which do not depend on its value". – Medinoc Jun 19 '13 at 09:42
  • 1
    Seems legal to me, too. – Massa Jun 19 '13 at 09:46
  • how do you plan to instantiate either an `A` or a `B` ? Both require the existence of an instance of the other type before they can be instantiated. – Sander De Dycker Jun 19 '13 at 10:18
  • @SanderDeDycker fizzer references the standard in the question. – Peter Wood Jun 19 '13 at 10:41
  • Those voting to close as duplicate: Yes, I've read the other question (I link to it). It's not the same - other poster uses aggregate initialization - and the answers he gets are speculative. – fizzer Jun 19 '13 at 11:21
  • @PeterWood : I understand that, but presumably having two separate classes `A` and `B` implies that they will be used separately too - otherwise what's the point of having two classes if you always have to use them in combination. – Sander De Dycker Jun 19 '13 at 11:37
  • @Sander They could be implementations of abstract classes. – Peter Wood Jun 19 '13 at 11:44
  • @PeterWood : fair point - I can see some value in that. – Sander De Dycker Jun 19 '13 at 11:52

1 Answers1

0

Perfectly legal. Clearly the storage of A and B are allocated as C is allocated prior to constructing C... thus the references to A and B are well-defined and can be used. However, you wouldn't be able to dereference the B object in the constructor of the A object. Oppositely, deferencing A in the constructor of B should be OK, although compiler support for any of this might be spotty...

mark
  • 5,269
  • 2
  • 21
  • 34
  • For grins I tried this in VS2012 and it 1) compiled fine, but unexpectedly 2) allowed me to derefernce B in constructor of A which resulted in accessing uninitialized memory. – mark Jun 19 '13 at 12:42