考虑以下代码段:
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/