2

If there is a C or C++ code like this:

if (func())
    ;

can compiler optimise out call to function func() if it cannot be sure whether function has any side-effects?

Origin of my question: I sometimes call assert macros in a way like this:

if (func())
    assert(0);

if I want to make sure that func() is always called and that asssertion fails in debug mode if func() returns wrong value. But recently I was warned that my code doesn't guarantee that function is always called.

faramir
  • 251
  • 4
  • 13
  • 2
    Can post the definition of `func`? – R Sahu Sep 23 '16 at 15:25
  • 1
    Why not `assert(!func())` or ` retval=func(); assert(!retval);`? – cxw Sep 23 '16 at 15:26
  • It is a common function that can have side effects. I don't want to discuss this for some particular function. Let's imagine that the function isn't implemented in the same file, so compiler doesn't have informations what is inside it. – faramir Sep 23 '16 at 15:28
  • 4
    if it cannot be sure of side effects it is not allowed to optimize it out. I dont understand the worries that the function might not be called. – 463035818_is_not_an_ai Sep 23 '16 at 15:28
  • 5
    @cxw If `func` actually *does* have side effects, `assert(!func())` is a bad idea. – Baum mit Augen Sep 23 '16 at 15:30
  • For `assert(!func())`, function isn't called in release mode. For ` retval=func(); assert(!retval);` we are facing possible dead code optimization. The question would be the same: If func() can have side effects, can it be optimised out? – faramir Sep 23 '16 at 15:30
  • *"we are facing possible dead code optimization"* - only if `retval` is known at compile time, and the dead code that might be eliminated is that in the `assert` (e.g. printing a message and exiting), and *not* any side effects of `func()`, which is unconditionally called. – Tony Delroy Sep 23 '16 at 15:33
  • Hmm if `assert` would return value then `func() && assert(0);` could be used. – Slava Sep 23 '16 at 15:44
  • @Slava Not really. As the result is unused and `assert(0);` has no side effects if `NDEBUG` is defined, this is just the same thing as the `if` stuff OP uses in the end. – Baum mit Augen Sep 23 '16 at 15:51
  • @BaummitAugen I am not saying that it would have different effect, but looks better. – Slava Sep 23 '16 at 15:53

2 Answers2

10

If the compiler cannot prove that optimizing away the call to func does not change the observable behavior of your program, it is not allowed to make the optimization.

So unless the compiler can prove that not calling the function has no observable effect, the call will take place. Note that compilers can be smart sometimes, so if you want to be sure, make sure the function actually does have a side effect. (On the other hand, if it doesn't, you need not care.)

This is known as the as-if rule.

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
3

(This is a C++ answer. Please post a question for one programming language only, not two.)

No, a function that may have side effects cannot be optimised out, because then you may be "optimising out" side effects. And since by "side effects" we really mean "the things that your program does", a compiler permitted to do such a thing would not be particularly useful. That's why the standard's "as-if" rule prevents the sort of optimisation you're talking about.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055