Please see the update for a better sample of the problem. The original code has a mix of issues which muddies the picture:
This question Why can I call a non-constexpr function inside a constexpr function? presented the following code
#include <stdio.h>
constexpr int f()
{
return printf("a side effect!\n");
}
int main()
{
char a[f()];
printf("%zd\n", sizeof a);
}
Which as I answer is ill-formed but gcc 4.8.2
allows it (see it live).
But, if we use the -fno-builtin
flag gcc
generates an error (see it live):
error: call to non-constexpr function 'int printf(const char*, ...)'
return printf("a side effect!\n");
^
so it seems
that gcc
is considering its builtin version of printf
to be a constant expression. gcc
documents builtins here but does not document this case where a builtin of a non-constexpr function can be considered a constant expression.
If this is indeed the case:
- Is a compiler allowed to to do this?
- If they are allowed, don't they have to document it to be conformant?
- Can this be considered an extension, if so, it seems like this would require a warning as the C++ draft standard section
1.4
Implementation compliance paragraph 8 says (emphasis mine):
A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any well-formed program. Implementations are required to diagnose programs that use such extensions that are ill-formed according to this International Standard. Having done so, however, they can compile and execute such programs.
Update
As Casey points out there are a few things going on in the original problem that makes it a poor example. A simple example would be using std::pow which is not a constexpr function:
#include <cmath>
#include <cstdio>
constexpr double f()
{
return std::pow( 2.0, 2.0 ) ;
}
int main()
{
constexpr double x = f() ;
printf( "%f\n", x ) ;
}
Compiles and builds with no warnings or error (see it live) but adding -fno-builtin
makes it generates an error (see it live). Note: why math functions are not constexpr in C++11:
error: call to non-constexpr function 'double pow(double, double)'
return std::pow( 2.0, 2.0 ) ;
^