Tor*_*ter 5 c++ clang constexpr c++14
我们来看一个这个简单的例子:
#include <iostream>
namespace foo {
constexpr int main(int argc, char* argv[]) {
// code
}
}
int main(int argc, char* argv[])
{
return foo::main(argc, argv);
}
Run Code Online (Sandbox Code Playgroud)
取决于代码是什么,clang会抱怨或不抱怨.如果代码是:
cout << "Hello!";
return 0;
Run Code Online (Sandbox Code Playgroud)
clang抱怨:
错误:constexpr函数永远不会产生常量表达式[-Winvalid-constexpr]
Run Code Online (Sandbox Code Playgroud)constexpr int main(int argc, char* argv[]) {注意:非constexpr函数'operator <<>'不能用于常量表达式
Run Code Online (Sandbox Code Playgroud)std::cout << "Hello!";/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/ostream:530:5:注意:在这里声明
Run Code Online (Sandbox Code Playgroud)operator<<(basic_ostream<char, _Traits>& __out, const char* __s)
很公平,constexpr函数不能包含任何cout语句,我们知道.但是如果我们这样做会发生什么?
for (int i = 0; i < argc; i++)
std::cout << argv[i];
Run Code Online (Sandbox Code Playgroud)
clang允许它!好吧,但这不可能是一个constexpr函数,即使它被标记为constexpr,让我们尝试在constexpr上下文中使用它.
int arr[foo::main(argc, argv)];
Run Code Online (Sandbox Code Playgroud)
有用!那一定是clang bug?我之所以说clang是因为gcc抱怨:
错误:constexpr函数的主体'constexpr int foo :: main(int,char**)'不是return语句
所以我的结论是铿锵有误,而gcc是对的.
Ric*_*ith 10
Clang在这里是正确的.
第一个例子
这里的代码是:
constexpr int foo::main(int argc, char* argv[]) {
std::cout << argv[i];
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在C++ 11中,此代码格式错误,因为正文包含一个表达式语句,这在constexpr函数定义中是不允许的.
在C++ 1y中,此代码格式错误,无需诊断,因为调用foo::main永远不会产生常量表达式(因为它总是调用operator<<(std::ostream&, const char*),而不是constexpr).
第二个例子
在这种情况下,代码是:
constexpr int foo::main(int argc, char* argv[]) {
for (int i = 0; i < argc; i++)
std::cout << argv[i];
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在C++ 11中,此代码for格式错误,因为它包含一个-statement.
在C++ 1y中,此代码有效.特别是,foo::main(0, 0)是一个常量表达式(带有值0).由于foo::main可以在常量表达式中使用,因此不允许Clang拒绝它,也不允许拒绝它.
第三个例子
int arr[foo::main(argc, argv)];
Run Code Online (Sandbox Code Playgroud)
这里绑定的数组不是常量表达式(因为它读取argc并且argv不是常量).但是,Clang默认支持可变长度数组作为扩展.您可以指定-pedantic-errors将clang置于严格一致的模式,并且在该模式下它将拒绝此代码.
海湾合作委员会的诊断:
错误:constexpr函数的主体'constexpr int foo :: main(int,char**)'不是return语句
在C++ 11和C++ 1y中都是不正确的.在C++ 11中,它是不正确的,因为规则更加微妙(constexpr函数体可以包含typedefs和一些其他结构,而不仅仅是return-statements).在C++ 1y中,规则根本不存在.
| 归档时间: |
|
| 查看次数: |
4441 次 |
| 最近记录: |