据我所知,这是 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++ 代码。
这是使用正确标志确实有很大帮助的情况之一,在 gcc 和 clang 中使用 -pedantic 会产生警告和错误,例如 gcc 说:
warning: ISO C++ forbids compound-literals [-Wpedantic]
auto a = &(int) { 1 };
^
error: taking address of temporary [-fpermissive]
如果我们使用-fpermissive is gcc,它确实允许编译这段代码。尽管旧版本似乎允许使用-Wno-address-of-temporary,但我无法在现代版本中使用任何标志构建此代码。我想知道 gcc 是否允许将其作为remnant of an old extension。
注意,问题Cryptic struct definition in C 有一个非常有趣的(取决于你对有趣的定义)复合文字的使用。
假设 Schism is correct 和 this question 是原始来源,然后在示例中的代码中使用:
if (setsockopt(server_connection.socket, SOL_SOCKET, SO_REUSEADDR, &(int) { 1 }, sizeof(int)) < 0) {
在 C99 和 C++ 中都是有效的用法。