在c++中&(int){1}是什么意思?

时间:2022-03-07 16:54:49

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?

我觉得这很奇怪,因为它看起来像是无效的语法。它使用一个block scope(?),中间有一个随机的1(没有分号)并获取地址。对我来说没什么意义。你们能开导我吗?

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

尝试了w/ c++ 11,所以它编译:

auto a = &(int) { 1 };

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

但是我不知道怎么处理这个变量。

2 个解决方案

#1


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:

就我所知这是一个复合文字,它是C99特性,它不是标准的c++,但是gcc和clang都支持它作为扩展:

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

ISO C99支持复合文字。复合文字看起来像一个包含初始化器的cast。它的值是在cast中指定的类型的对象,包含初始化器中指定的元素;这是一个左值。作为扩展,GCC在C90模式和c++中支持复合文本,尽管在c++中语义略有不同。

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

通常,指定的类型是一个结构。假设结构foo和结构声明如下所示:

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

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

这里有一个用复合文字构造struct foo的例子:

 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:

在这种情况下,a的类型将指针指向int。

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.

在C语言中,复合文字表示具有静态或自动存储持续时间的未命名对象。在c++中,复合文字指定了一个临时对象,这个对象只存在到它的全表达式的末尾。

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.

因此,使用c++获取地址可能不是一个好主意,因为对象的生命周期在整个表达式的末尾结束。虽然,它可能是仅仅依赖于未定义行为的c++代码。

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:

在这种情况下,使用正确的标志真的很有帮助,在gcc和clang中使用-pedantic都会产生警告和错误,例如gcc说:

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.

如果我们使用- fperative is gcc,它确实允许编译这段代码。我无法让clang在现代版本中使用任何标志构建此代码,尽管旧版本似乎允许它使用- wno -address-临时性。我不知道gcc是否允许它作为旧扩展的残余。

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

注意,在C中隐含的问题结构定义有一个非常有趣的(取决于你对有趣的定义)使用复合文字。

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

在C99和c++中都是有效的用法。

#2


5  

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

它获取包含一个匿名整数的临时匿名结构的地址,该整数通过C99指定的初始化器初始化。原因是setsockopt不想要一个整数,而是一个指向它的指针(或者更确切地说,一个指向某个东西的指针,以及这个东西的大小)。

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.

…但是它没有引入blah。

#1


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:

就我所知这是一个复合文字,它是C99特性,它不是标准的c++,但是gcc和clang都支持它作为扩展:

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

ISO C99支持复合文字。复合文字看起来像一个包含初始化器的cast。它的值是在cast中指定的类型的对象,包含初始化器中指定的元素;这是一个左值。作为扩展,GCC在C90模式和c++中支持复合文本,尽管在c++中语义略有不同。

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

通常,指定的类型是一个结构。假设结构foo和结构声明如下所示:

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

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

这里有一个用复合文字构造struct foo的例子:

 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:

在这种情况下,a的类型将指针指向int。

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.

在C语言中,复合文字表示具有静态或自动存储持续时间的未命名对象。在c++中,复合文字指定了一个临时对象,这个对象只存在到它的全表达式的末尾。

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.

因此,使用c++获取地址可能不是一个好主意,因为对象的生命周期在整个表达式的末尾结束。虽然,它可能是仅仅依赖于未定义行为的c++代码。

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:

在这种情况下,使用正确的标志真的很有帮助,在gcc和clang中使用-pedantic都会产生警告和错误,例如gcc说:

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.

如果我们使用- fperative is gcc,它确实允许编译这段代码。我无法让clang在现代版本中使用任何标志构建此代码,尽管旧版本似乎允许它使用- wno -address-临时性。我不知道gcc是否允许它作为旧扩展的残余。

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

注意,在C中隐含的问题结构定义有一个非常有趣的(取决于你对有趣的定义)使用复合文字。

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

在C99和c++中都是有效的用法。

#2


5  

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

它获取包含一个匿名整数的临时匿名结构的地址,该整数通过C99指定的初始化器初始化。原因是setsockopt不想要一个整数,而是一个指向它的指针(或者更确切地说,一个指向某个东西的指针,以及这个东西的大小)。

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.

…但是它没有引入blah。