Home > Back-end >  How does gcc compile C functions in a constexpr context?
How does gcc compile C functions in a constexpr context?

Time:12-30

Given that the C standard library doesn't provide constexpr versions of the cmath functions, consider the program below.

#include <cmath>
#include <cstring>

int main()
{
    constexpr auto a = std::pow(2, 10);
    constexpr auto b = std::strlen("ABC");
}

As expected, MSVC and clang fail to compile this, because constexpr variables are initialized from functions that are not declared constexpr.

g , however, compiles this. The version of g doesn't seem to matter.

(See them all in compiler explorer)

How does g achieve this? Is this correct (allowed) compiler behavior?

CodePudding user response:

The resolution of LWG 2013 was that implementations are not allowed to declare non-constexpr functions as constexpr, so gcc is non-conformant by allowing these to be evaluated at compile time.

That said, GCC does not actually mark the needed functions as constexpr. What it instead does is replace those calls very early on with __builtin_pow and __builtin_strlen, which it can compute at compile time (the std:: versions call the libc versions, which can't). This is a compiler extension.

If you compile with -fno-builtin, it also fails to compile both std::pow and std::strlen, but you can make both clang and GCC compile this by explicitly writing out __builtin_pow(2, 10) and __builtin_strlen("ABC").

CodePudding user response:

As noted, the C standard library doesn't currently support constexpr evaluation of cmath functions. However, that doesn't prevent individual implementations from having non-standard code. GCC has a nonconforming extension that allows constexpr evaluation.

  • Related