I came across the page about C++20 bit field initialization https://en.cppreference.com/w/cpp/language/bit_field#Cpp20_Default_member_initializers_for_bit_fields , where for C++20 the following example present (simplified here):
struct S {
int z : 1 || new int { 0 };
};
The page does not explain the construction || new int
|| new int
. Is there any dynamic allocation here new int
? What is the default value of z
, is it {0}
? Could you please clarify?
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.