Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does &(int) { 1 } mean in C++?

Tags:

c++

c99

I saw this here and I don't know what it means:

&(int) { 1 } 

I thought it was weird because it seems like invalid syntax. It's casting a block scope(?) with a random 1 in the middle (without a semi-colon) and taking the address. Doesn't make a lot of sense to me. Could you guys enlighten me?

Tried it out w/ C++11, so it compiles:

auto a = &(int) { 1 }; 

But I have no idea what to do with the variable.

like image 800
Enu Ynu Ti Avatar asked Jul 28 '15 02:07

Enu Ynu Ti


People also ask

What does the fox say Meaning?

Speaking of the meaning of the song, Vegard characterizes it as coming from "a genuine wonder of what the fox says, because we didn't know". Although interpreted by some commentators as a reference to the furry fandom, the brothers have stated they did not know about its existence when producing "The Fox".

How can I find a song by the sound?

On your phone, touch and hold the Home button or say "Hey Google." Ask "What's this song?" Play a song or hum, whistle, or sing the melody of a song. Hum, whistle, or sing: Google Assistant will identify potential matches for the song.

What does the fox say for real?

One of the most common fox vocalizations is a raspy bark. Scientists believe foxes use this barking sound to identify themselves and communicate with other foxes. Another eerie fox vocalization is a type of high-pitched howl that's almost like a scream.


2 Answers

As far as I can tell this is a compound literal, it is C99 feature, it is not standard C++ but both gcc and clang support it as an extension:

ISO C99 supports compound literals. A compound literal looks like a cast containing an initializer. Its value is an object of the type specified in the cast, containing the elements specified in the initializer; it is an lvalue. As an extension, GCC supports compound literals in C90 mode and in C++, though the semantics are somewhat different in C++.

Usually, the specified type is a structure. Assume that struct foo and structure are declared as shown:

 struct foo {int a; char b[2];} structure; 

Here is an example of constructing a struct foo with a compound literal:

 structure = ((struct foo) {x + y, 'a', 0}); 

This is equivalent to writing the following:

 {    struct foo temp = {x + y, 'a', 0};    struct 

In this case the type of a would pointer to int. Hopefully this was originally C code since as the gcc document says:

In C, a compound literal designates an unnamed object with static or automatic storage duration. In C++, a compound literal designates a temporary object, which only lives until the end of its full-expression.

and so taking the address in C++ is probably a bad idea since the lifetime of the object is over at the end of the full-expression. Although, it could have been C++ code which just relied on undefined behavior.

This is one of those cases where using the correct flags really helps a lot, in both gcc and clang using -pedantic will produce a warning and an error, for example gcc says:

warning: ISO C++ forbids compound-literals [-Wpedantic]  auto a = &(int) { 1 };                      ^ error: taking address of temporary [-fpermissive] 

if we use -fpermissive is gcc it indeed does allow this code to compile. I can not get clang to build this code with any flags in modern versions although old versions seem to allow it using -Wno-address-of-temporary. I wonder if gcc allows this as a remnant of an old extension.

Note, the question Cryptic struct definition in C has a pretty interesting(depending on your definition of interesting) use of compound literals.

Assuming Schism is correct and this question is the original source then the use in that code in the example:

if (setsockopt(server_connection.socket, SOL_SOCKET, SO_REUSEADDR, &(int) { 1 }, sizeof(int)) < 0) { 

is a valid use in both C99 and C++.

like image 200
Shafik Yaghmour Avatar answered Oct 04 '22 14:10

Shafik Yaghmour


It's not immediately obvious, but if you look at the surrounding code, it becomes clear what it is used for, and what it has to be.

It's taking the address of a temporary anonymous struct containing a single anonymous integer which is initialized via a C99 designated initializer. The reason is that setsockopt doesn't want an integer, but a pointer to it (or rather, a pointer to something, and the something's size).

In other words, it's a very cool hack to provide a kind-of integer argument (without an explicit temp variable) to a function that expects a pointer.

So, it's functionally identical to:

int blah = 1; setsockopt(..., &blah, ...); 

... except it works without introducing blah.

like image 24
Damon Avatar answered Oct 04 '22 16:10

Damon