Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
315 views
in Technique[技术] by (71.8m points)

c++ - Why can I call a non-constexpr function inside a constexpr function?

Consider the following code:

#include <stdio.h>

constexpr int f()
{
    return printf("a side effect!
");
}

int main()
{
    char a[f()];
    printf("%zd
", sizeof a);
}

I would have expected the compiler to complain about the call to printf inside f, because f is supposed to be constexpr, but printf is not. Why does the program compile and print 15?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The program is ill-formed and requires no diagnostic according to the C++11 draft standard section 7.1.5 The constexpr specifier paragraph 5 which says:

For a constexpr function, if no function argument values exist such that the function invocation substitution would produce a constant expression (5.19), the program is ill-formed; no diagnostic required.

and provides the following example:

constexpr int f(bool b)
  { return b ? throw 0 : 0; } // OK
constexpr int f() { return f(true); } // ill-formed, no diagnostic required

and section 5.19 paragraph 2 says:

A conditional-expression is a core constant expression unless it involves one of the following as a potentially evaluated subexpression [...]

and includes:

— an invocation of a function other than a constexpr constructor for a literal class or a constexpr function [ Note: Overload resolution (13.3) is applied as usual —end note ];

We would probably prefer a diagnostic in this case, it could just be an oversight, I have a bug report for a similar situation where gcc does not produce an error but we would probably like it to: Is the compiler allowed leeway in what it considers undefined behavior in a constant expression?.

Update

Using the -fno-builtin flag will cause gcc to generate the following error:

 error: call to non-constexpr function 'int printf(const char*, ...)'
 return printf("a side effect!
");
                                 ^

So gcc does consider this ill-formed it is just ignores it when it is using the builtin version of printf.

Although somewhat inconsistently using the -pedantic produces the following warning:

warning: ISO C++ forbids variable length array 'a' [-Wvla]
 char a[f()];
           ^

Note that using f() to initialized a constexpr variable:

constexpr int x = f() ;

does generate an error:

error: 'printf(((const char*)"a side effect!12"))' is not a constant expression

Note that additionally in the more general case a compiler is not allowed mark standard library functions as constexpr unless explicitly allowed by the standard.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...