Reputation: 1534
I have a piece of code which basically adds some constant number to all elements of an array
Matrix a.array() += 32768; //Bad due to hard coded literal
Matrix has scalar type of unsigned short int
.
Some other options I am exploring are as following:
Matrix a.array() += std::numeric_limits<Matrix::Scalar>::max()/2 + 1;
and
Matrix a.array() += (std::numeric_limits<Matrix::Scalar>::max() >> 1) + 1;
The second solution looks most readable to me, but do I pay a penalty compared to the 1st option. Does any standard compiler will precompute this during compile time?
I am currently using gcc 4.6.3, but I am not using C++11 due to some dependencies on older code.
Update:
From my limited knowledge of the assembly output, I'll say that the compiler is not optimizing it. The story is same even with -std=c++0x flag.
Here are the assembly outputs:
Using Method 2 with -std=c++0x flag
Hardcoded Literal (See line 26)
Update2
Using -O2 flags produces identical assembly files irrespective of -std=c++0x flag use or not.
Conclusion
Since optimization flags like -O2 does the correct job, Method2 probably is the best practice. Also since these codes are now part of a class member methods, I ended up using a private const variable intialized to std::numeric_limits<MyMatrix::Scalar>::max()/2 + 1
Upvotes: 0
Views: 897
Reputation: 1795
Previously you could declare something as const
and someone could override it's const
ness so the compiler might not have optimised your code. With C++11 you can declare something constexpr
which says, "Yes really, this is a constant, and you can use it at compile time". What this means is that any constexpr
functions with constexpr
arguments can be evaluated at compile time.
So what does this mean in your particular case? If you're using C++11 (which I highly recommend) then as the function std::numeric_limits<unsigned short int>::max()
is declared as a constexpr
it will be optimised out at compile time.
Enabling c++11 is usually as simple as setting a compiler flag.
Upvotes: 1