views:

110

answers:

3

Consider following function:

void func(const char & input){
 //do something
}

Apparently it makes sense for the parameter to be constant value not reference to constant regarding size of the char type, Now may a compiler optimize that to constant value so that it'll be the same as following ?

void func(const char input){
 //do something
}
+5  A: 

No. This is not equivalent. In the first case, input can still change, e.g. if it's a reference to a variable that's modified by another thread.

Henrik
Yes but what if what you are referencing to is already constant, I believe that that is what the OP means
the_drow
Or even in a single-threaded program. This function might call another function that modifies the referenced variable. Or the reference might alias a global variable, and the function itself might change it!
Jason Orendorff
@the_drow there isn't a way of telling the compiler that a referenced value is immutable. If it inlines the function, then it can deduce that it will not change and can then perform the optimisation on the code generated for the inlined call, but if you only consider the function not the function call it can't.
Pete Kirkham
If it may be changed by another thread, shouldn't it be volatile?
Pedro d'Aquino
@the_drow: as Pete said, "const" only tells the compiler "don't let this code change the variable" - it doesn't mean that other code (e.g. another thread, an ISR, etc) can't change it.
Dan
@Pedro d'Aquino_nice point.
Pooria
+1  A: 

As noted, not in general. But what the compiler can do is inline the entire function call. And if the parameter supplied is a compile time constant, it can do lots of interesting optimizations.

jdv
+2  A: 

Like someone stated, but was sadly downvoted (not sure why he did delete his answer), the compiler can do any and everything as long as the observable behavior is the same as if it did not do anything different.

It's self-expanatory that if your function writes into the reference, and a global variable was passed as argument to the function and the global was later printed after the function returns, or anything else fancy is done, then if the compiler would change the parameter passing convention, it's more difficult for the compiler to prove you still get the same observable behavior. If the compiler can't prove it, it can't do the desired optimization.

So whatever further question comes up, just think "it can do anything as long as I won't notice it".

Johannes Schaub - litb
This doesn't make sense. The function can't write into a const reference, and the compiler can't assume that nobody else can, so it can't change the calling sequence.
EJP
@EJP This was just an example for a scenario that makes things more difficult. But it can perfectly write if the const is casted away. This is valid if the argument passed actually refers to a non-const object. It could also take the address of the parameter and safe it somewhere, for another example where such optimizations can't usually be done.
Johannes Schaub - litb
So if the function can write though the reference it isn't a safe optimization, because the rest of the program can notice.
EJP
@EJB: I think litb summed it up well. If the compiler can prove the optimization will not have any affect on observed behavior then it can do the optimization. Now we can come up with all sorts of reasons that would stop it from doing the optimization and the compiler would have to be able to check all of these, If it can't guarantee that it has no affect then it can't do the optimization (which will be most of the time). But in those small corner cases it may just be able to prove it.
Martin York
It is safe as long as the compiler can prove to itself it isn't observable. I don't find these corner cases that might exist very credible, nor the concept thatba real compiler writer would pursue such a low-returning optimization. I'm a compiler writer, and I wouldn't.
EJP
@Johannes Schaub_nice point even a reference to a non-constant an be optimized away, hadn't noticed it!
Pooria
Um please disregard my previous comment (if the change wouldn't carry out to the caller, `i` will never be incremented and the loop will never terminate...). I deleted my comment, since @Martin's got a nice explanation of it already.
Johannes Schaub - litb
@EJP_I don't think commercial and industrial compilers would ignore these kind of cases so easily.
Pooria
@EJP_check out const_cast<>() macro and see how easy it'll cast constants to non-constants.
Pooria
@Johannes Schaub_ What if the function is gonna become a DLL, in this case how can compiler get to know if the referenced object will not be used by multiple threads and may not change during function execution by another thread?
Pooria
@Pooria that is exactly my point. If the compiler made this so-called 'optimization' the cast-away-const assignment would have no effect on the actual parameter because it would only change the formal argument in the method's stack frame, and unless the compiler could detect that that difference was unobservable it wouldn't make the optimization. As for 'commerical and industrial compilers', all you need is some evidence. It's clear that the standard permits it, however the original question here is 'will it happen'. I beg leave to doubt it.
EJP
@EJP_Actually I think volatile keyword has something to do with this issue, declaring the referenced object as volatile will tell the compiler that it might change by something other than the main thread like another thread, check out the following link http://msdn.microsoft.com/en-us/library/145yc477(v=VS.90).aspx.
Pooria