1

Let's consider the following code:

class A {
public:
   constexpr A(int value) : m_value(value);
private:
   const int m_value;
};

void f(const A& a);

f(42); // OK
f(std::rand()); // KO - How to detect this case?

Is there a way to determine if A is built at compile time or run-time?

Thomas Moulard
  • 5,151
  • 2
  • 21
  • 28
  • Admittedly, I don't use C++ a whole lot, so please correct me if I'm wrong, but isn't the whole point of `constexpr` to guarantee that the expression is indeed built at compile-time? – Dolda2000 Mar 24 '15 at 03:30
  • No, constexpr indicates that it should if it possible. This is just an indication actually http://stackoverflow.com/questions/14248235/when-does-a-constexpr-function-get-evaluated-at-compile-time – Thomas Moulard Mar 24 '15 at 03:32
  • It seems to me that the answer to the question you linked rather confirms my statement: "*`constexpr` functions* will *be evaluated at compile time when all its arguments are constant expressions and the result is used in a constant expression as well.*" – Dolda2000 Mar 24 '15 at 03:34
  • f(42) will be constructed at compile time, f(std::rand()) will not :) – Thomas Moulard Mar 24 '15 at 03:35
  • Indeed, since its arguments aren't `constexpr`s, in accordance with the quote. – Dolda2000 Mar 24 '15 at 03:36
  • Indeed, I rephrased my question. I want to be able to warn the user that they are using the API in a sub-optimal way somehow. – Thomas Moulard Mar 24 '15 at 03:39
  • There is no way to disallow runtime usage of a constexpr function such as `A::A(int)`. For this we need constexpr function parameters which do not exist in C++11/14, i.e. `A::A(constexpr int)` (not legal C++ as of now). – n. m. could be an AI Mar 24 '15 at 03:51
  • I would like to rely on overloading, see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3583.pdf (9.4 Forbidding Runtime Execution with Overloading) but I cannot come up with an example that compiles... – Thomas Moulard Mar 24 '15 at 06:19

1 Answers1

0

One way to verify that an expression is indeed a constexpr is to assign it to a constexpr variable:

int main()
{
    constexpr int a = f(42);
    constexpr int b = f(std::rand());
    return(0);
}

Since the value constexpr variables must be computable by the compiler, the assignment of b will produce an error. GCC says the following:

foo.cpp:25:35: error: call to non-constexpr function ‘int rand()’
     constexpr int b = f(std::rand());

I'm not sure if it can be done in a way to merely produce a warning, however.

Dolda2000
  • 25,216
  • 4
  • 51
  • 92