Let's say I write a class Foo with a constructor Foo(int). And I have this piece of code:
Foo a(i), b = a + Foo(2);
If I call the constructor in the code with a constant, does the compiler run it once, and store the result for run-time, or is it executed at run-time?
There are two levels to this:
- is it possible and legal w.r.t. the Standard for a perfect optimiser -- achieving everything an expert person could potentially do with unlimited effort and genius - to do this at compile time,
and
- is compile-time behaviour required / guaranteed by the Standard.
Is i
a compile time constant? If not, and the value of i
passed to Foo::Foo(i)
influence its behaviour (whether affecting data member values or side-effects like logging), then clearly it's inherently impossible to construct Foo(i) at compile time. If i
is constant, it may still be inherently impossible - for example the constructor implementation may have behaviour based on the current time, or need to consult some other run-time data. Such problems may also prevent Foo(2)
being possible to evaluate at compile-time.
If i
is constant, and Foo
's constructor doesn't depend on other runtime-only data, then it is possible to optimise. But, there's nothing in your code that requires the C++ Standard to even attempt any optimisation, let alone be capable of optimising this away. The same is true of the +
operator invoked on the Foo
s... it may be legal to optimise, but is certainly not required.
In practice, I would expect most current mainstream compiler to optimise simple cases of Foo(i)
for compile-time constant i
, but be challenged by resolving the addition. If you really want to know, try it for your compiler at various optimisation levels....
Assuming that it executes at run-time (which I believe to be the case), is there a way to make it run at compile-time, or have the same effects as if it were run as such?
Yes... you may get some milage out of constexpr
, which is a keyword introduced with C++11 that tells the compiler it's required to resolve certain values at compile time (if you constexpr
for variables/values that the compiler isn't required to support at compile time it will report an error).
Secondly, it's often possible to express compile time operations using templates. To get yourself started in that direction, you may want to search for "C++ template factorial compiletime" or similar to see how basic calculations can be coded.