10

I want to experiment with migrating a project from gcc to clang++. I admit ignorance on my part, I'm not sure why the following bit of code

template <typename T>
constexpr T pi{std::acos(T(-1.0))};

compiles silently with g++ but clang++ produces the error

trig.hpp:3:13: error: constexpr variable 'pi<float>' must be initialized by a constant expression
constexpr T pi{std::acos(T(-1.0))};

and I was hoping someone who knows more about it than I do could enlighten me.

NB: Tried with -std=C++14 and C++1y. Fails under clang version 3.6.2 (tags/RELEASE_362/final). Works with g++ (GCC) 5.2.0.

Barry
  • 286,269
  • 29
  • 621
  • 977
Timtro
  • 418
  • 5
  • 15
  • 3
    Looks related to [Is it a conforming compiler extension to treat non-constexpr standard library functions as constexpr?](http://stackoverflow.com/q/27744079/1708801) – Shafik Yaghmour Sep 28 '15 at 01:45
  • @ShafikYaghmour I thought I searched well. I was wrong. Thank you. This is a disappointing result indeed. I'm also surprised that GCC doesn't at least emit a warning when it's going to allow something forbidden in the standard. I was compiling with -pedantic too! If you want to write an answer, I'll accept it. – Timtro Sep 28 '15 at 01:51
  • 1
    I am not surprised that question did not come up, the overlap in keywords seems minimal. When I first ran into this about a year ago I could not find anything and it was not until I accidentally ran into the language working group issue 2013 when I managed to put the pieces together. – Shafik Yaghmour Sep 28 '15 at 02:07

1 Answers1

13

Clang is correct here, we are not allowed to use acos in a constant expression.

The issue is that acos is not marked constexpr in the standard but gcc treats some functions not marked in the standard including acos as constexpr. This is a non-conforming extension and should eventually be fixed in gcc.

Builtin functions are often used to constant fold and we can see if we use -fno-builtin with gcc it disables this non-conforming behavior and we will receive the following error:

error: call to non-constexpr function 'double acos(double)'
constexpr T pi{std::acos(T(-1.0))};
                         ^
Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740