-1

I want to know whether the gcc compiler optimizes the following method calls.

bool methodY()
{
  ..some operations..
  return true;
}


int methodX() {
  if(methodY() == true)
    return methodY();

  ..some operations..
}

Inside the methodX, will the compiler optimize calling of methodY two times or it will just let it be?

mschuurmans
  • 1,088
  • 1
  • 12
  • 24
  • What is `..some operations..`? Put a print in there and you'll find that it will call it twice. – Blaze Nov 02 '18 at 10:40
  • 4
    Why is this tagged *C*? (On a completely other note: `== true` is redundant, tautologous and superfluous.) – Biffen Nov 02 '18 at 10:40
  • this would depend on what `..some operations..` exactly are. If the method only returns `true` the compiler might even not call the method at all – 463035818_is_not_an_ai Nov 02 '18 at 10:41
  • Well, it has to execute that method, it has "some operations ..", but if that method returns only true, then it eligible for optimization. – Abhi Nov 02 '18 at 10:41
  • 1
    Wouldn't it be "easier" and more "optimized" to `bool result=methodY(); if result, return result`? – M.K Nov 02 '18 at 10:41
  • Usually no. There is no way gcc can determine that `methodY` has no side effects without full source access. – Matthieu Brucher Nov 02 '18 at 10:42
  • 3
    @M.K Or just `if (methodY()) return true;` No need to store a variable if it’s always going to have the same value when used. – Biffen Nov 02 '18 at 10:43
  • Even simpler: `if (methodY() == true) return true;`. But, no, normally nothing will be optimized away, as `methodY` might have side effects. But depending on the `methodY()` function, the compiler might optimize away the second call to `methodY()` if it can be sure that `methodY()` has no side effects, but you really should not care, instead you should not write code like this. – Jabberwocky Nov 02 '18 at 10:49
  • 1
    Why not simply take a look in the generated assembly? And why not writing some more elaborated code instead? If the call is really needed two times, it will be done, otherwise not. If not, why writing such code? Any human reader will struggle here! – Klaus Nov 02 '18 at 10:49
  • 1
    Code like that would look weird to me as a reader so i'd avoid it for that reason. The compiler is allowed to optimise away the second `methodY()` call if the function itself has no side effects. – George Nov 02 '18 at 10:52
  • 2
    why do you want to know? The compiler generates output that behaves as-if it would do exactly what you told it to do. If `methodX` has sideeffects you dont have to worry that they will be executed one time too little. If it does not you still dont have to care too much about optimizations but better care about writing readable code – 463035818_is_not_an_ai Nov 02 '18 at 10:53
  • btw as I do understand the tags, the `optimization` tag would be more appropriate, as the `compiler-optimization` tag is for questions regarding tweaking the compiler (using flags and options) in contrast to tweaking the code – 463035818_is_not_an_ai Nov 02 '18 at 11:12

1 Answers1

1

.. will the compiler optimize calling of methodY two times or it will just let it be?

There is no rule for that. It depends on the compiler.

For instance, if methodY always return true, the compiler is allowed to optimize your code by inlining methodY like:

int methodX() {
  ..some operations..  (from methodY)
  ..some operations..  (from methodY)
  return true;
}

But whether it will do it, we can't tell by just looking at the C++ source.

With gcc you can use the option -S to generate an assembly source file (.s file). Looking into that file is the way to tell what the compiler did.

There are also some online site like https://godbolt.org/ that you can use. Here is an example:

#include <stdio.h>

int methodY()
{
  printf("y\n");
  return 1;
}

int methodX() {
  if(methodY() == 1)
    return methodY();

  return 0;
}

int main(){
  if (methodX()) printf("m\n");
  return 0;
}

compiled with -O3 it shows:

.LC0:
  .string "y"
methodY():
  sub rsp, 8
  mov edi, OFFSET FLAT:.LC0
  call puts
  mov eax, 1
  add rsp, 8
  ret
methodX():
  sub rsp, 8
  mov edi, OFFSET FLAT:.LC0
  call puts
  mov edi, OFFSET FLAT:.LC0
  call puts
  mov eax, 1
  add rsp, 8
  ret
.LC1:
  .string "m"
main:
  sub rsp, 8
  mov edi, OFFSET FLAT:.LC0
  call puts
  mov edi, OFFSET FLAT:.LC0
  call puts
  mov edi, OFFSET FLAT:.LC1
  call puts
  xor eax, eax
  add rsp, 8
  ret

As you can see main never calls methodX but simply do the three prints directly. So in this case the functions were optimized away.

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
  • there is a rule. See eg here: https://stackoverflow.com/questions/15718262/what-exactly-is-the-as-if-rule – 463035818_is_not_an_ai Nov 02 '18 at 11:16
  • @user463035818 That's a different rule. It's not a rule for whether the compiler optimizes a function call. And.. as you can see from the assembly example, the compiler **did** optimize away the function call **while** still obeying the "as-if" rule – Support Ukraine Nov 02 '18 at 11:20
  • the compiler is allowed to optimize out the function call if the observable behaviour is the same as with the function call. Why do you think this case is different? – 463035818_is_not_an_ai Nov 02 '18 at 11:20
  • @user463035818 The "as-if" rule always apply but there is no rule for whether or not the compiler will optimize OPs code – Support Ukraine Nov 02 '18 at 11:22
  • what is the as-if rule about if not whether the compiler is allowed to optimize something out or not? Nevermind, maybe I am just misunderstanding what you are trying to say – 463035818_is_not_an_ai Nov 02 '18 at 11:26
  • 1
    @user463035818 yes, I think you are misunderstanding what I'm trying to say. The "as-if" rule describes (as you correctly say) **how** the compiler is allowed to do optimizations. But the "as-if" rule does **not** tell **whether** the compiler will do optimizations. And that is what OP is asking - quote: "..will the compiler optimize.." and the answer is that there is no rule that the compiler **will* – Support Ukraine Nov 02 '18 at 12:15