lundi 2 octobre 2023

C++: Rules for this return {} initialization

I am trying to understand the rules governing the following initialization:

struct A {
  const char* s_ptr;
  std::string str;
};

A Foo() {
  return {};
}

A a = Foo();

As per my understanding, a.s_ptr == nullptr and a.str is "empty" string (using string default constructor).

Here's my understanding of the C++ rules which dictate this result.

return {}; statement is copy list initialization (also mentioned here).

Since A is an aggregate, this rule applies:

(dcl.init.list#3.4) Otherwise, if T is an aggregate, aggregate initialization is performed

I am guessing since 3.4 is before 3.5, so it applies first.

For aggregate initialization, these rules apply:

(dcl.init.aggr#5) For a non-union aggregate, each element that is not an explicitly initialized element is initialized as follows:

  • (5.1) If the element has a default member initializer ([class.mem]), the element is initialized from that initializer.
  • (5.2) Otherwise, if the element is not a reference, the element is copy-initialized from an empty initializer list ([dcl.init.list]).

5.2 is used for both A::s_ptr and A::str above.

A::s_ptr is initialized using this rule:

(dcl.init.list#3.11) Otherwise, if the initializer list has no elements, the object is value-initialized.

A::str is initialized using this rule:

(dcl.init.list#3.5) Otherwise, if the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.

Is my understanding correct?

Aucun commentaire:

Enregistrer un commentaire