Having read about the most vexing parse, I experimented a bit and found this program. There are two very similar lines. One of them yields warnings in both g++7 and clang++-
There is no difference in parsing. Both cases are covered by simple-type-specifier followed by optional parenthesized expression-list.
The semantic meaning is specified in C++17 (N4659) [expr.type.conv]/2:
If the type is cv
void
and the initializer is()
, the expression is a prvalue of the specified type that performs no initialization. Otherwise, the expression is a prvalue of the specified type whose result object is direct-initialized with the initializer.
This specifically says that void()
is a prvalue of type void
.
Now, I'm sure that it is not intended that a prvalue of type void be illegal, as it is a common occurrence, e.g. (void)x;
or calling a void function!
But I can't find where in the Standard it says that temporary materialization should be suppressed for void
prvalues. The [class.temporary]/2 seems to say that a discarded-value expression always materializes a temporary; and it is an error to materialize a prvalue of incomplete type. Maybe it is a defect in the standard.
The difference in warning about "unused value" is probably because an unused value of type void
is a common occurrence and it would not be helpful to warn about.