enum class E {
One,
Two
};
void foo(E value = decltype(value)::One) {
}
It can be compiled with Clang (3.9), but cannot be compiled with GCC 6.1: value was not declared in this scope
.
What compiler is right?
enum class E {
One,
Two
};
void foo(E value = decltype(value)::One) {
}
It can be compiled with Clang (3.9), but cannot be compiled with GCC 6.1: value was not declared in this scope
.
What compiler is right?
According to [basic.scope.pdecl]/1:
The point of declaration for a name is immediately after its complete declarator (Clause 8) and before its initializer (if any), except as noted below.
So the parameter is definitely declared at that point. How about using it in decltype
? Wording was outdated and inadvertently disallowed it. See core issue 2082:
According to 8.3.6 [dcl.fct.default] paragraph 9,
A default argument is evaluated each time the function is called with no argument for the corresponding parameter. The order of evaluation of function arguments is unspecified. Consequently, parameters of a function shall not be used in a default argument, even if they are not evaluated. This prohibits use of parameters in unevaluated operands, e.g.,
void foo(int a = decltype(a){});
This wording predates the concept of “unevaluated operands” (the phrase “not evaluated” refers to calls to the function where an actual argument is supplied and thus the default argument is not used, not to unevaluated operands) and should not apply to such cases.
So the quoted paragraph was amended to read
A parameter shall not appear as a potentially-evaluated expression in a default argument.
Since operands of decltype
are unevaluated, this is fine now, and GCC is wrong.
© 2022 - 2024 — McMap. All rights reserved.
int h(int a, int b = sizeof(a));
is used in an example as an error, so I'd say this isn't allowed, after all. – Lesliedecltype(value)
is not a potentially evaluated expression. – Badlandssizeof(a)
as being illegal. – Sorgo