According to the C++17 standard (11.3.6 Default arguments)
9 A default argument is evaluated each time the function is called
with no argument for the corresponding parameter. A parameter shall
not appear as a potentially-evaluated expression in a default
argument. Parameters of a function declared before a default
argument are in scope and can hide namespace and class member name
It provides the following example:
int h(int a, int b = sizeof(a)); // OK, unevaluated operand
So, this function declaration
void f(int y = sizeof(y)) {}
is correct because, in this expression sizeof(y)
, y
is not an evaluated operand, based on C++17 8.3.3 Sizeof:
1 The sizeof operator yields the number of bytes in the object
representation of its operand. The operand is either an expression,
which is an unevaluated operand (Clause 8), or a parenthesized
type-id.
and C++17 6.3.2 Point of declaration:
1 The point of declaration for a name is immediately after its
complete declarator (Clause 11) and before its initializer (if any),
except as noted below.