What does &(int) { 1 } mean in C++? [duplicate]
Asked Answered
R

2

29

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.

Riti answered 28/7, 2015 at 2:4 Comment(5)
Any context where this is from? It doesn't compile by itself...Rhodia
Looks like a compound literal but not sure without more context, more likely it was C code since it is supported as an extension in C++ and taking the address of it would probably be a bad idea since the semantic are different.Geiger
@awesomeyi I dont remember. And it's common for code found on google not to compile anywaysRiti
@awesomeyi It can be found on this hot question from CR!Lithic
@Lithic although that seems possible the OP does not seem to have an account on that site, so it would be helpful if the OP can confirm that this is indeed the case.Geiger
G
32

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

Geiger answered 28/7, 2015 at 2:17 Comment(0)
A
6

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.

Atli answered 28/7, 2015 at 18:15 Comment(2)
I am a little wary of assuming that reference is the same one the OP referred to ... Schism implied in a comment that is where it came from but the OP as not confirmed that yet. The link was added by another user not the OP.Geiger
@ShafikYaghmour: Ah, I didn't notice that comment wasn't from the OP, thought it was.Atli

© 2022 - 2024 — McMap. All rights reserved.