当您尝试使用constexpr时,main如下所示:
constexpr int main()
Run Code Online (Sandbox Code Playgroud)
gcc和clang抱怨:
错误:无法声明':: main'为内联
错误:'main'不允许声明为constexpr
让我们看看constexpr函数的要求是什么:
constexpr函数必须满足以下要求:
什么是LiteralType?
文字类型是以下任何一种
功能主体必须包括什么?
以下示例:
constexpr int main() { ; }
constexpr int main() { return 42; }
constexpr int main() {
// main defaults to return 0
}
Run Code Online (Sandbox Code Playgroud)
似乎符合所有这些要求.还有这个,main是在程序开始之前运行的特殊功能.您可以从main运行constexpr函数,并且为了将constexpr标记为constexpr,它必须在constexpr上下文中运行.
那么为什么main不允许成为constexpr?
我们来看一个这个简单的例子:
#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语句 …