News for hackers. Stuff that matters.
Re:Fun with C++26 reflection: Keyword Arguments by pilianas on Tuesday February 11, 2025 @07:17AM (#43011949)
You still don't need to syntactically require same order initialization, it's an easy job for a compiler to reorder things so that all dependencies work out - every language with order independent declarations have to do that for example.
Re:Fun with C++26 reflection: Keyword Arguments by drysine on Tuesday February 11, 2025 @08:26AM (#43012474)
In a general case you can't do that with separate compilation. [0]

  struct A { A(A*); };

  A* f(struct B *b);

  struct B {
    A a1;
    A a2;
    B(): a1(f(this)), a2(f(this)) {}
  };

  //in a different translation unit
  A* f(B *b)
  {
    return &b->a1; //or a2, we don't know
  }

[0] https://godbolt.org/z/xMb64ssYK
Re:Fun with C++26 reflection: Keyword Arguments by kccqzy on Tuesday February 11, 2025 @10:45AM (#43014158)
Your code snippet does not use the designated initializer feature that this comment thread is talking about.

Furthermore your code possibly contains undefined behavior depending on the behavior of the constructor of A.

Re:Fun with C++26 reflection: Keyword Arguments by drysine on Monday February 17, 2025 @03:33AM (#43076614)
As I stated above, it's the same kind of situation. See my another comment in this thread for an example with designated initializers.

>your code possibly contains undefined behavior

Only if f() returns a pointer to a2 (which is my point). Or did you imply that in the case when f() returns a pointer to a1 and it gets passed to the constructor of a1, provenance matters?

Re:Fun with C++26 reflection: Keyword Arguments by drysine on Thursday February 20, 2025 @03:34PM (#43119808)
Actually, provenance matters:

"During the construction of an object, if the value of the object or any of its subobjects is accessed through a glvalue that is not obtained, directly or indirectly, from the constructor's this pointer, the value of the object or subobject thus obtained is unspecified." [0]

Reading an unspecified value isn't UB, that's good, but I don't understand why the standard says 'unspecified' because it clearly can be indeterminate if a sub-object hasn't been initialized yet.

[0] https://eel.is/c++draft/class.cdtor#2

Re:Fun with C++26 reflection: Keyword Arguments by likpok on Tuesday February 11, 2025 @11:43AM (#43014944)
You don't need to require same-order initialization, but allowing people to do different orders will be confusing when actions are reordered behind the scenes. Especially imagine if there are dependencies between the objects you're passing in.

  struct A {
    B one;
    C two;
  };
  struct B {
    B() {
      cout << "init B" << endl;
    }
  }
  struct C {
    C() {
      cout << "init C" << endl;
    }
  }

Mixing up the order is confusing:

  A{.two=B(),.one=A()}
since `two` is initialized after `one` despite coming before (the comma operator <expr a>, <expr b> usually means `expr a` happens before `expr b`.

This case is a little contrived, but run the evolution forward: you can have members that depend on each other, or have complex initialization logic of their own. There, debugging the specific order of events is important.

Re:Fun with C++26 reflection: Keyword Arguments by xmcqdpt2 on Wednesday February 12, 2025 @06:51AM (#43024406)
Scala does it by pulling out the keyword arguments to variables so that your example would become

{ val x$1 = B() val x$2 = A() A(.one = x$2, .two = x$1) }

This maintains left-to-right evaluation order while allowing you to pass arguments in any order.

There is probably some dark and forbidden reason why C++ can't do that.

ETA: That's basically what the post does.