When using aggregate / designated initialization of a struct it is possible to refer to another field like this:
#include <stdio.h>
int main()
{
struct
{
int a;
int b;
}
s =
{
.a = 3,
.b = s.a + 1,
};
return 0;
}
We use s.a in the initialization of s.b. However, we need to refer to s.a through s. Is it possible to refer directly to s.a as just .a
, or similar? This would for instance make it possible to use the same syntax when initializing arrays of structs like here:
int main()
{
struct
{
int a;
int b;
}
s[] =
{
{
.a = 3,
.b = s[0].a + 1,
},
{
.a = 5,
.b = s[1].a - 1,
}
};
return 0;
}
Here we could maybe write something like .b = .a - 1
instead of .b = s[1].a - 1
.
Is it possible to refer directly to
s.a
as just.a
, or similar?
No, .a
in this context is a designator, and it cannot be referred to in the brace-or-equal-initializer used to initialize a given data member by means of its matching designator.
struct Bar { int a; };
struct Foo {
int a;
Bar b;
};
int main() {
Foo f = {
// ^ start of braced-init-list
.a
// ^^ designator (for data member of Foo)
= 1,
// ^^^ initializer-clause
.b{.a = 2}
// ^^^^^^^^ braced-init-list
// referring to a designator of a
// data member of Bar
};
}
Designated initializers, a new C++20 feature introduced by P0329R4, are part of the grammar for braced-init-lists:
braced-init-list: { initializer-list ,opt } { designated-initializer-list ,opt } { }
where the grammar of designated-initializer-list is:
designated-initializer-list: designated-initializer-clause designated-initializer-list , designated-initializer-clause
and, where the grammar for the individual designated-initializer-clause:s is:
designated-initializer-clause: designator brace-or-equal-initializer
and where finally, a designator is:
designator: . identifier
Now, a brace-or-equal-initializer does not allow, in any way, to refer to another designator of the same object. Note here the difference here between designators and other identifiers, e.g. referring to data members of the struct as part of the initializer-clause or nested braced-init-list:s of the brace-or-equal-initializer.