我看到了这个here,我不知道这意味着什么:
&(int) { 1 }
我觉得这很奇怪,因为它似乎是无效的语法。它正在构建一个块范围(?),中间有一个随机1(没有分号)并取地址。对我来说没有多大意义。你们能开导我吗?
用C ++ 11试了一下,所以编译:
auto a = &(int) { 1 };
但我不知道如何处理变量。
答案 0 :(得分:32)
据我所知,这是一个compound literal,它是C99功能,它是not standard C++,但gcc和clang都支持它作为扩展名:
ISO C99支持复合文字。复合文字看起来像包含初始值设定项的强制转换。它的值是转换中指定类型的对象,包含初始值设定项中指定的元素;这是一个左值。作为扩展,GCC支持C90模式和C ++中的复合文字,尽管语义在C ++中有些不同。
通常,指定的类型是结构。假设struct foo和 结构声明如下:
struct foo {int a; char b[2];} structure;
以下是使用复合构造struct foo的示例 字面:
structure = ((struct foo) {x + y, 'a', 0});
这相当于写下以下内容:
{ struct foo temp = {x + y, 'a', 0}; struct
在这种情况下,a
的类型将指向int。希望这是最初的C代码,因为gcc文档说:
在C中,复合文字指定具有静态或自动存储持续时间的未命名对象。在C ++中,复合文字指定一个临时对象,该对象只存在于其完整表达式的结尾。
所以在C ++中获取地址可能是一个坏主意,因为对象的生命周期在完整表达式结束时结束。虽然,它可能是C ++代码,它只依赖于未定义的行为。
这是使用正确标志确实有很大帮助的情况之一,在使用-pedantic的gcc和clang中都会产生警告和错误,例如gcc说:
warning: ISO C++ forbids compound-literals [-Wpedantic]
auto a = &(int) { 1 };
^
error: taking address of temporary [-fpermissive]
如果我们使用-fpermissive
是gcc,它确实允许这个代码编译。虽然旧版本似乎允许使用-Wno-address-of-temporary
,但我无法用现代版本中的任何标志来构建此代码。我想知道gcc是否允许这个为remnant of an old extension。
注意,问题Cryptic struct definition in C非常有趣(取决于你对有趣的的定义)使用复合文字。
假设分裂is correct和this question是原始来源,则在示例中使用该代码:
if (setsockopt(server_connection.socket, SOL_SOCKET, SO_REUSEADDR, &(int) { 1 }, sizeof(int)) < 0) {
在C99和C ++中都是有效的用法。
答案 1 :(得分:5)
这并不是显而易见的,但是如果你看一下周围的代码,它就会变得清晰,它的用途是什么,以及它必须是什么。
它取一个临时匿名结构的地址,该结构包含一个匿名整数,该整数通过C99指定的初始化程序初始化。原因是setsockopt
不需要整数,而是指向它的指针(或者更确切地说,指向某事的指针,以及某些东西的大小)。
换句话说,为一个需要指针的函数提供一种整数参数(没有显式的临时变量)是一个非常酷的 hack。
因此,它在功能上与:
相同int blah = 1;
setsockopt(..., &blah, ...);
...除了在不引入blah
的情况下有效。