You compile your code in C++1y mode which contains wording to relax constexpr
restrictions including all looping statements.
Have a look at N3652 which introduced these changes.
Question
Let's take this simple example:
#include <iostream>
namespace foo {
constexpr int main(int argc, char* argv[]) {
// code
}
}
int main(int argc, char* argv[])
{
return foo::main(argc, argv);
}
Depend on what code is, clang will complain or no. If code is:
cout << "Hello!";
return 0;
clang complains:
error: constexpr function never produces a constant expression [-Winvalid-constexpr]
constexpr int main(int argc, char* argv[]) {
note: non-constexpr function 'operator<< >' cannot be used in a constant expression
std::cout << "Hello!";
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/ostream:530:5: note: declared here
operator<<(basic_ostream<char, _Traits>& __out, const char* __s)
Fair enough, constexpr functions can't contain any cout statements, as we know. But what happens if we do this?
for (int i = 0; i < argc; i++)
std::cout << argv[i];
clang allows it! OK, but this can't possibly be a constexpr function even though it is marked constexpr, let's try to use it in constexpr context.
int arr[foo::main(argc, argv)];
It works! So it must be clang bug? Reason I say clang because gcc complains:
error: body of constexpr function 'constexpr int foo::main(int, char**)' not a return-statement
So my conclusion is clang is wrong and gcc is right.
Solution 2
You compile your code in C++1y mode which contains wording to relax constexpr
restrictions including all looping statements.
Have a look at N3652 which introduced these changes.
OTHER TIPS
Clang is correct here.
First example
Here, the code is:
constexpr int foo::main(int argc, char* argv[]) {
std::cout << argv[i];
return 0;
}
In C++11, this code is ill-formed, because the body contains an expression-statement, which is not permitted in a constexpr
function definition.
In C++1y, this code is ill-formed with no diagnostic required, because a call to foo::main
can never produce a constant expression (because it always calls operator<<(std::ostream&, const char*)
, which is not constexpr
).
Second example
In this case, the code is:
constexpr int foo::main(int argc, char* argv[]) {
for (int i = 0; i < argc; i++)
std::cout << argv[i];
return 0;
}
In C++11, this code is ill-formed, because it contains a for
-statement.
In C++1y, this code is valid. In particular, foo::main(0, 0)
is a constant expression (with value 0
). Since foo::main
is usable in a constant expression, Clang is not permitted to reject it, and does not do so.
Third example
int arr[foo::main(argc, argv)];
The array bound here is not a constant expression (because it reads argc
and argv
, which are not constant). However, Clang supports variable-length arrays as an extension by default. You can specify -pedantic-errors
to put clang into strictly-conforming mode, and in that mode it will reject this code.
GCC's diagnostic:
error: body of constexpr function 'constexpr int foo::main(int, char**)' not a return-statement
is incorrect in both C++11 and C++1y. In C++11, it's incorrect because the rule is more subtle (the body of a constexpr
function can contain typedef
s and a few other constructs, not just return
-statements). In C++1y, the rule no longer exists at all.
So gcc 4.8.1 does not implement relaxed constexpr restraints, but clang 3.5 does. My mistake was that clang and gcc both have variable length array extensions. if I had used std::array instead, both compilers would reject the code. What I still don't understand is if clang allows relaxed constexpr, then why is it not a constexpr?