我在这里看到了这个,但我不知道它的意思:
&(int) { 1 }
我认为这很奇怪,因为它看起来像是无效的语法。它将一个带有随机1的块范围进行转换(没有分号),然后取地址。对我来说没有太多意义。你们能给我解释一下吗?
我已经尝试了C++11,可以编译:
auto a = &(int) { 1 };
但是我不知道该如何处理这个变量。
我在这里看到了这个,但我不知道它的意思:
&(int) { 1 }
我认为这很奇怪,因为它看起来像是无效的语法。它将一个带有随机1的块范围进行转换(没有分号),然后取地址。对我来说没有太多意义。你们能给我解释一下吗?
我已经尝试了C++11,可以编译:
auto a = &(int) { 1 };
但是我不知道该如何处理这个变量。
在这种情况下,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
a
的类型将指向 int。希望最初的代码是 C 代码,因为 gcc 文档中说:
在 C 中,复合字面值指定具有静态或自动存储期的无名对象。在 C++ 中,复合字面值指定一个临时对象,该对象仅存在于其完整表达式结束之前。
因此,在 C++ 中获取地址可能不是一个好主意,因为对象的生命周期在完整表达式结束时结束。虽然它可能是依赖于未定义行为的 C++ 代码。
这是其中一种使用正确标志真正有所帮助的情况,在 gcc 和 clang 中使用 -pedantic 将产生警告和错误,例如,gcc 会说:
warning: ISO C++ forbids compound-literals [-Wpedantic]
auto a = &(int) { 1 };
^
error: taking address of temporary [-fpermissive]
-fpermissive
,它确实允许编译此代码。我无法使用任何标志在现代版本中使clang构建此代码,尽管旧版本似乎允许使用-Wno-address-of-temporary
。我想知道gcc是否将其作为旧扩展的遗留物允许。if (setsockopt(server_connection.socket, SOL_SOCKET, SO_REUSEADDR, &(int) { 1 }, sizeof(int)) < 0) {
在C99和C++中都是有效的用法。
这段代码的作用并不是立即显而易见的,但如果您查看周围的代码,就会明确其使用方法和要求。
它获取一个临时匿名结构体的地址,该结构体包含一个匿名整数,该整数通过C99指定的初始化器进行初始化。原因是setsockopt
不想要一个整数,而是指向它的指针(或者更准确地说,是指向某个东西的指针以及该东西的大小)。
换句话说,这是一种非常酷的技巧,可以为预期要求指针的函数提供类似于整数参数的内容(而无需显式地创建临时变量)。
因此,从功能上讲,它与以下代码完全相同:
int blah = 1;
setsockopt(..., &blah, ...);
...除了不需要引入blah
之外,它可以正常工作。