Bit field initialization in C++20 with `|| new int` construction

Viewed 155
1 Answers

There are two ways to parse this declaration:

  • int z : (1 || new int) { 0 };

  • int z : (1 || new int { 0 });

where everything inside () is interpreted as the size specifier. Since "the longest sequence of tokens that forms a valid size is chosen" as indicated by cppreference, the second alternative is assumed. Therefore, by short-circuiting (the second operand to the || operator is not evaluated if the first operand is true), the declaration is equivalent to

int z : 1;

with no default value for the bit field.


The rule governing this ambiguity resolution can be found in [class.mem]/9:

In a member-declarator for a bit-field, the constant-expression is parsed as the longest sequence of tokens that could syntactically form a constant-expression.

Syntactically, a constant-expression is defined as follows:

constant-expression:
  conditional-expression

Thus, a top-level assignment operator is not accepted, but ?: is okay. Compare two examples from the linked cppreference page:

int x1 : 8 = 42;                 // OK; "= 42" is brace-or-equal-initializer
int y1 : true ? 8 : a = 42;      // OK; brace-or-equal-initializer is absent

which, subject to the aforementioned specification, are parsed respectively as:

int x1 : (8) = 42;
int y1 : (true ? 8 : a = 42);

where () again denotes the expression that is parsed as the size specifier.

Related