c++ - void({}) 中的 {} 是什么?

标签 c++ gcc clang c++14 language-lawyer

考虑以下代码段:

auto f() { return void({}); }
int main() { f(); }

void({})中的{}究竟是什么?
它是如何解释的?

当然,只是出于好奇。无论如何,让我们走得更远。

请注意,GCC 6.1 和 clang 3.8 编译它都没有错误 (-std=c++14 -pedantic)。
后者不提示,前者显示警告:

warning: list-initializer for non-class type must not be parenthesized

使用 -pedantic-errors 代替,GCC 在 clang 编译时以错误结束。

这种差异是否是两个编译器之一的错误?
我的意思是,它是否应该被接受的有效代码?

最佳答案

void 类型的转换以及返回 void 值的可能性从一开始就存在于 C++ 语言中。提出问题的唯一部分是 {} 在此上下文中的作用。

clang 的快速实验

int a({});

生成一条错误消息说

error: cannot initialize a variable of type 'int' with an rvalue of type 'void'

表示 clang 将 {} 解释为 void 值。这似乎是一种非标准行为。我在语言规范中没有看到任何地方会说 {} 在这种情况下应该产生一个 void 值。

但是由于clang中恰好是这种情况,所以void({})在clang中编译并没有什么异常。 C++ 中的任何值都可以转换为 void 类型,这意味着只要编译器在此上下文中接受 {},其余的就自然而然地遵循。

在 GCC 中实际上是 -pedantic-errors 模式下的错误

error: list-initializer for non-class type must not be parenthesized

正式地说,这是一个“错误”,而不是 GCC 中的“警告”。


这里实际发生的是打开 ({ 和关闭 }) 的组合使这些编译器将其解释为称为 Statement Expression 的 GNU C 语言扩展。 (顺便说一句,clang 也支持)。例如,这就是编译以下代码的原因

int a = ({ 3; });

在该扩展下,表达式 ({}) 被视为 void 类型的语句表达式。但是,这与 C++ 中的统一初始化语法相冲突。

关于c++ - void({}) 中的 {} 是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41131806/

相关文章:

c++ - OpenGL 中对 R8G8B8 纹理的 NPOT 支持

c++ - 如何释放绑定(bind)参数 boost::signals2::signal 保留的引用?

c++ - 如何仅针对一个开关盒 block 禁用 "enumeration value not explicitly handled in switch"?

c++ - 发布版本与调试版本的运行方式不同的一些原因是什么

c++ - C/C++ 控制CPU使用率

c++ - 为什么 __builtin_parity 是相反的?

c++ - 为什么 C++ 链接器在构建期间需要库文件,即使我是动态链接的?

c - 为什么 GCC 的 -Wconversion 对于 char 与 unsigned char 的行为不同?

c++ - 如何使用 Clang 将链接器警告视为错误?

c++ - 为什么 const 左值引用可以引用可变右值引用?