Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does gcc compile C functions in a constexpr context?

Given that the C++ standard library doesn't (currently) 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?

like image 696
Drew Dormann Avatar asked Dec 29 '21 18:12

Drew Dormann


People also ask

Are constexpr functions evaluated at compile-time?

A constexpr function that is eligible to be evaluated at compile-time will only be evaluated at compile-time if the return value is used where a constant expression is required. Otherwise, compile-time evaluation is not guaranteed.

Can a function be constexpr?

constexpr functionsA constexpr function is one whose return value is computable at compile time when consuming code requires it. Consuming code requires the return value at compile time to initialize a constexpr variable, or to provide a non-type template argument.

How do I know if a function is constexpr?

The easiest way to check whether a function (e.g., foo ) is constexpr is to assign its return value to a constexpr as below: constexpr auto i = foo(); if the returned value is not constexpr compilation will fail.

Is constexpr faster?

Try it on your code baseNot only will your code be faster and smaller, it'll be safer. Code marked constexpr can't bitrot as easily.

Are constexpr functions always evaluated at compile time?

@Herb Sutter: The general expectation seems to be that constexpr functions are always evaluated at compile time. Cedric's comment is a clear example of that, he says "This is all about optimization". And hence expect that constexpr functions are always evaluated at compile time, regardless of its context. To me, they are all about expressiveness...

What is the use of constexpr in C++?

constexpr function can call only other constexpr function not simple function. The function should not be of a void type and some operators like prefix increment (++v) are not allowed in constexpr function. It removes the function calls as it evaluates the code/expressions in compile time.

What is GCC compiler?

GCC is a collection of compilers and libraries that offer support for various programming languages such as C, C++, Java, etc. The GCC compiler is included in most Linux distributions. In this article, we have used Ubuntu for all the examples. gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 Copyright (C) 2019 Free Software Foundation, Inc.

What is the difference between C++ 11 and C++ 14 constexpr?

In C++ 11, a constexpr function should contain only one return statement. C++ 14 allows more than one statement. constexpr function should refer only to constant global variables. constexpr function can call only other constexpr function not simple function.


Video Answer


2 Answers

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").

like image 128
Artyer Avatar answered Nov 15 '22 00:11

Artyer


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.

like image 23
Deev Avatar answered Nov 14 '22 22:11

Deev