Conversions to void
type as well as the possibility to returning a void
value have been present in C++ language since very beginning. The only part that raises questions is the role of {}
in this context.
A quick experiment with clang
int a({});
generates an error message saying
error: cannot initialize a variable of type 'int' with an rvalue of type 'void'
which indicates that clang interprets {}
as a void
value. This appears to be a non-standard behavior. I don't see any place in language specification that would say that {}
should produce a void
value in this context.
But since this happens to be the case in clang, there's nothing unusual in void({})
compiling in clang. Any value in C++ can be converted to void
type, meaning that as long as the compiler accepts {}
in this context, the rest just follows naturally.
In GCC it is actually an error in -pedantic-errors
mode
error: list-initializer for non-class type must not be parenthesized
so formally it is an "error", not a "warning" in GCC.
What actually happens here is that the combination of opening ({
and closing })
makes these compilers to interpret it as a GNU C language extension known as Statement Expression (which is incidentally supported by clang as well). This is, for example, what makes the following code compile
int a = ({ 3; });
Under that extension, the expression ({})
is seen as a statement expression of void
type. However, this conflicts with the uniform initialization syntax in C++.
void
. – T.C.[](){}
not({})
– Chemistpp(void) unused
goes via [expr.cast]/4.2 to [expr.static.cast]/6.void(unused)
goes to [expr.cast] via the first sentence of [expr.type.conv]/2 ("If the initializer is a parenthesized single expression, the type conversion expression is equivalent (in definedness, and if defined in meaning) to the corresponding cast expression.") The problem is that({})
is not a "parenthesized single expression", because{}
is not an expression. – T.C.