1

Please can someone clarify (I'm using Visual Studio 15.9.2):

In the following code given that Pi_cnst is evaluated at run time (because defining Pi in this way requires a run time calculation), will RAD2DEG_cnst ever be evaluated at compile time or is the use of "constexpr" always reverting to "const" ?

edit - add: If it is always reverting to const then should I expect a warning, or is it bad in some other way i.e. it seems odd to be able to so easily declare a constexpr for the body to be accepted but ALWAYS be such that it is never actually a constexpr. What have I missed?

constexpr double Pi_error = std::acos(-1.0); //error function call must have a constant value in a constant expression (does not compile)
const double Pi_cnst = std::acos(-1.0); //ok evaluated at run time

constexpr double Pi_expr = 3.1415926; //ok valid constexpr

constexpr double RAD2DEG_cnst(double rad) { return rad * 180.0 / Pi_cnst; } //no error or warning BUT is this ever evaluated at compile time?
constexpr double RAD2DEG_expr(double rad) { return rad * 180.0 / Pi_expr; } //ok can be evaluated at compile time

const double result1 = RAD2DEG_cnst(0.1); //evaluated at run time?
const double result2 = RAD2DEG_expr(0.2); //evaluated at compile time?

double myVariable = 0.3;
const double result3 = RAD2DEG_expr(myVariable); //ok - but can only be evaluated at run time

const double myOtherVariable = 0.4;
const double result4 = RAD2DEG_expr(myOtherVariable); //ok - evaluated at compile time because parameter is CONST?

I found also constexpr function and its parameter and constexpr vs const vs constexpr const .

DefinedRisk
  • 140
  • 9
  • What's the question? You saw that `acos`didn't work within a constexpr. – Matthieu Brucher Nov 21 '18 at 15:17
  • @MatthieuBrucher: `Pi_cnst` cannot be `constexpr` because of `acos` but `RAD2DEG_cnst` is `constexpr` although it relies on `Pi_cnst`. I believe the question is: how can it be declared as `constexpr` while performing un`constexpr`able operations, and what does it mean in practice about compile-time evaluation? – papagaga Nov 21 '18 at 15:21
  • Oh, OK. I think constexpr doesn't always been a build time... – Matthieu Brucher Nov 21 '18 at 15:23
  • I get an error for `RAD2DEG_cnst` with gcc9 though: "In function 'constexpr double RAD2DEG_cnst(double)': error: the value of 'Pi_cnst' is not usable in a constant expression" – papagaga Nov 21 '18 at 15:23
  • 1
    Possible duplicate of [When does a constexpr function get evaluated at compile time?](https://stackoverflow.com/questions/14248235/when-does-a-constexpr-function-get-evaluated-at-compile-time) – Matthieu Brucher Nov 21 '18 at 15:23
  • acos is too complex a function to be able to make it constexpr so that's why you cant assign its result to a constexpr variable – Serve Laurijssen Nov 21 '18 at 15:28

1 Answers1

3

Your code is ill-formed, no diagnostic required. In

constexpr double RAD2DEG_cnst(double rad) { return rad * 180.0 / Pi_cnst; }

There is no input which will ever make the function a core constant expression which is specified by [dcl.constexpr]/5

For a constexpr function or constexpr constructor that is neither defaulted nor a template, if no argument values exist such that an invocation of the function or constructor could be an evaluated subexpression of a core constant expression, or, for a constructor, a constant initializer for some object ([basic.start.static]), the program is ill-formed, no diagnostic required.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402