Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's {} in void({})?

Consider the following snippet:

auto f() { return void({}); }
int main() { f(); }

What's exactly the {} in void({})?
How is it interpreted?

Just out of curiosity, of course. Let's go a bit further anyway.

Note that both GCC 6.1 and clang 3.8 compile it with no errors (-std=c++14 -pedantic).
The latter doesn't complain, the former shows a warning:

warning: list-initializer for non-class type must not be parenthesized

Using -pedantic-errors instead, GCC ends with an error while clang compiles it.

Is this discrepancy an error of one of the two compilers?
I mean, is it valid code that should be accepted or not?

like image 488
skypjack Avatar asked Dec 13 '16 22:12

skypjack


People also ask

What is void main () in C?

The void main() indicates that the main() function will not return any value, but the int main() indicates that the main() can return integer type data. When our program is simple, and it is not going to terminate before reaching the last line of the code, or the code is error free, then we can use the void main().

What does JavaScript void () do?

Description. This operator allows evaluating expressions that produce a value into places where an expression that evaluates to undefined is desired. The void operator is often used merely to obtain the undefined primitive value, usually using void(0) (which is equivalent to void 0 ).

What does void * func () mean?

Void as a Function Return TypeThe void function accomplishes its task and then returns control to the caller. The void function call is a stand-alone statement. For example, a function that prints a message doesn't return a value. The code in C++ takes the form: void printmessage ( )

What type is void *?

The void data type has no values and no operations. It's a data type that represents the lack of a data type. Many programming languages need a data type to define the lack of return value to indicate that nothing is being returned.


1 Answers

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++.

like image 137
AnT Avatar answered Oct 04 '22 04:10

AnT