Reputation: 2281
In C++, does a mathematical declaration in a constant variable initialization costs some extra processing? Or modern compilers would automatically put the result of the mathematical calculation inside the variable when creating the .exe file?
So e.g.:
MyClass::MyClass()
{
const qint32 defaultX = 20;
poButton1 = new PushButton(this);
poButton1->move(defaultX,20);
poButton1 = new PushButton(this);
poButton1->move(defaultX,80);
//...
}
is a example of a code that uses a constant variable (defaultX) across a method usage (the constructor in this case). Now sometimes it's better for the developer to tell where the value came from:
MyClass::MyClass()
{
const qint32 defaultX = 800/2 - 244 + 12 + 32 - 180; //just an example!
poButton1 = new PushButton(this);
poButton1->move(defaultX,20);
poButton1 = new PushButton(this);
poButton1->move(defaultX,80);
//...
}
Of course he could just put that inside a comment, but let's suppose he wants to do it this way (e.g.: he is dumb). The question would then be: when a object of that class is being initialized, does that whole mathematical expression is calculated (costing extra processing) or when the .exe is created by modern compilers it already contains the optimized code seen in the first MyClass code?
Upvotes: 1
Views: 1595
Reputation: 158619
It is not guaranteed but most modern compilers will indeed fold the constant expression, the draft C++ standard has a note that says constant expressions could be evaluated during translation, from section 5.19
Constant expressions:
[ Note: Constant expressionscan be evaluated during translation.—end note ]
but we can run an experiment on godbolt with the following code:
#include <iostream>
int func()
{
const int defaultX = 800/2 - 244 + 12 + 32 - 180; //just an example!
return defaultX ;
}
int main()
{
std::cout << func() ;
}
and see it does indeed fold it to the following:
func():
movl $20, %eax #,
ret
In C++11 you can always use constexpr to make sure it is evaluated at compile time:
constexpr int defaultX = 800/2 - 244 + 12 + 32 - 180;
The standard does make one important note with respect to floating point constant expressions. Since there is a lack of specification on the accuracy of floating point operations it is possible that evaluations at run-time and compile-time could produce different results:
[ Note: Although in some contexts constant expressions must be evaluated during program translation, others may be evaluated during program execution. Since this International Standard imposes no restrictions on the accuracy of floating-point operations, it is unspecified whether the evaluation of a floating-point expression during translation yields the same result as the evaluation of the same expression (or the same operations on the same values) during program execution.84 Example:
bool f() { char array[1 + int(1 + 0.2 - 0.1 - 0.1)]; // Must be evaluated during translation int size = 1 + int(1 + 0.2 - 0.1 - 0.1); // May be evaluated at runtime return sizeof(array) == size; }
It is unspecified whether the value of f() will be true or false. —end example ] —end note ]
Upvotes: 3
Reputation: 211720
If it can be collapsed into a single value, which it must be in the case of a simple assignment, the compiler should take care of condensing it down to a singular value, though this may depend on your compiler's optimization flags. You may want to look at the instructions emitted by your compiler to be sure.
One way to express this more clearly is to declare the constant outside of the class itself but local to the implementation and use that within the class:
const qint32 myClassDefaultX = 800/2 - 244 + 12 + 32 - 180;
MyClass::MyClass() { ... }
Upvotes: 2