Reputation: 8277
for(int i = 0; i < my_function(MY_CONSTANT); ++i){
//code using i
}
In this example, will my_function(MY_CONSTANT)
be evaluated at each iteration, or will it be stored automatically? Would this depend on the optimization flags used?
Upvotes: 2
Views: 1177
Reputation: 158469
A modern optimizing compiler under the as-if rule
may be able to optimize away the function call in the case that you outlined in your comment here. The as-if rule
says that conforming compiler only has the emulate the observable behavior, we can see this by going to the draft C++ standard section 1.9
Program execution which says:
[...]Rather, conforming implementations are required to emulate (only) the observable behavior of the abstract machine as explained below.5
So if you are using a constant expression and my_function
does not have observable side effects it could be optimized out. We can put together a simple test (see it live on godbolt):
#include <stdio.h>
#define blah 10
int func( int x )
{
return x + 20 ;
}
void withConstant( int y )
{
for(int i = 0; i < func(blah); i++)
{
printf("%d ", i ) ;
}
}
void withoutConstant(int y)
{
for(int i = 0; i < func(i+y); i++)
{
printf("%d ", i ) ;
}
}
In the case of withConstant
we can see it optimizes the computation:
cmpl $30, %ebx #, i
and even in the case of withoutConstant
it inlines the calculation instead of performing a function call:
leal 0(%rbp,%rbx), %eax #, D.2605
Upvotes: 2
Reputation: 16099
If my_function
is declared constexpr and the argument is really a constant, the value is calculated at compile time and thereby fulfilling the "as-if" and "sequential-consistency with no data-race" rule.
constexpr my_function(const int c);
If your function has side effects it would prevent the compiler from moving it out of the for-loop
as it would not fulfil the "as-if" rule, unless the compiler can reason its way out of it.
The compiler might inline my_function
, reduce on it as if it was part of the loop and with constant reduction find out that its really only a constant, de-facto removing the call and replacing it with a constant.
int my_function(const int c) {
return 17+c; // inline and constant reduced to the value.
}
So the answer to your question is ... maybe!
Upvotes: 1
Reputation: 145279
It has to work as if the function is called each time.
However, if the compiler can prove that the function result will be the same each time, it can optimize under the “as if” rule.
E.g. this usually happens with calls to .end()
for standard containers.
General advice: when in doubt about whether to micro-optimize a piece of code,
In other words, decide whether to use a variable based on how clear the code then is, not on imagined performance.
Upvotes: 10
Reputation: 117876
It will be evaluated each iteration. You can save the extra computation time by doing something like
const int stop = my_function(MY_CONSTANT);
for(int i = 0; i < stop; ++i){
//code using i
}
Upvotes: 3