The following paper contains a rough draft of wording for standardizing
popular statement expressions extension.
With a side goal to enable them for evaluation as constant expressions.
A continue
statement with an identifier operand shall appear
within the body of a statement named by the label with the
corresponding identifier.
A break
statement with an identifier operand shall appear
within the body of a switch or iteration statement
named by the label with the corresponding identifier.
statement-expression:
( compound-statement )
A statement expression allows a block of statements to be treated as an expression, enabling the evaluation of the last statement within the block to yield a value.
Jumps via jumps statements shall not enter into any statement-expression.
Jumps via jumps statements shall not exit statement-expression.
Evaluation of a statement-expression is not interleaved with the evaluation of other parts of the containing expression.
The value and type of statement-expression are the same as of
the last statement within its compound-statement, as if they were
returned via a return
statement. 1
If the compound-statement is empty, or its last statement is not an expression, the statement-expressions is a void expressions.
Objects declared within the compound-statement have block scope, and their lifetime is confined to the statement-expression.
For a statement-expression to be a constant expression2,
it can consists only of statements evaluated during translation
(like constant expressions, contstexpr
declarations,
or static_assert
).
EXAMPLE 1 Statement expression as function-like macro
#define BIT(type, n) ({ \
static_assert(n >= 0 && n < sizeof(type) * CHAR_BIT); \
(type)1 << (n); \
})
int arr[BIT(unsigned int, 2)];
EXAMPLE 2 Statement expression as constant expression
unsigned char foo[({
static_assert(sizeof (int) >= 4);
constexpr auto s = sizeof (int);
10 * s;
})];
Implementations may allow jumping out of statement expressions via means of jumps statements.