1

Will conditional statement be evaluated even thought there is no valid statement inside conditional statement block? If yes, how to optimize the code for not to evaluate the conditional statement in this case? For ex:

if( get_value() !=NULL)
{
}

or

if( get_value() != NULL)
{
 do{}while(0);
}

In multiple places, in an existing project, just to get the debug prints, there are checks like this. Prints can be nullified using macro function but how to optimize the conditional statements? It is very difficult to remove these comparisons manually

Ramesh K
  • 77
  • 1
  • 6
  • This will depend on compiler optimization. Some compilers will check for conditions that does n't make any effect and remove it. – niyasc Feb 18 '16 at 11:29
  • Why do you need this code? You can simply do `if (! get_value())` and do the _important stuff_ there. – ForceBru Feb 18 '16 at 11:29
  • Depends on the compiler and the optimizer... Some uC code optimizer may even compile longer code to smaller size file because the longer code happen to match (in the assembly level) with another subroutine somewhere while the shorter one doesn't. But in general, it won't do any good... – Ian Feb 18 '16 at 11:34
  • In multiple places, in an existing project, just to get the debug prints, there are checks like this. Prints can be nullified using macro function but how to optimize the conditional statements? It is very difficult to remove these comparisons manually. – Ramesh K Feb 18 '16 at 11:35
  • 1
    @RameshK Include that information in the question. It makes the question relevant. – 2501 Feb 18 '16 at 11:36
  • @RameshK In my experience, it is never a good idea to make a decision based on the fact that bad code is frequent and/or difficult to remove unless that decision is to turn the bad code into good code. Find/replace will do wonders.. just sayin'. – Neil Feb 18 '16 at 11:38
  • @RameshK please modify your question and show the _debug print_ part. – Jabberwocky Feb 18 '16 at 11:38
  • 2
    If the `get_value` function has any observable behaviour then you will see that behaviour – M.M Feb 18 '16 at 11:39

1 Answers1

1

The C and C++ standards require that the compiler to ensure that get_value() is evaluated (or at least to behave as-if it were evaluated).

So in the general case, get_value will be evaluated. You can easily check this with godbolt:

extern int* get_value();

int func() {
  if( get_value() !=NULL)
  {
  }
}

Produces the x86 assembly on gcc 4.4.7 as follows:

    sub     rsp, 8
    call    get_value()
    add     rsp, 8
    ret

Note that get_value() is called, but the != NULL check doesn't happen since that comparison is not observable. So for this compiler, you can say that a strict sense that the full comparison is not evaluated, but the comparison is not fully eliminated since get_value must still be called (which is likely the expensive part).

The compiler is forced to take this path since it has no idea what side effects get_value may have, so it must call it. It is free to ignore the return value since it knows that the comparison and empty if-statement body have no effect.

In one special case, however, the compiler could eliminate the entire statement - if it can prove at compile-time that the get_value method has no side-effect. This is possible if the get_value method is declared in the same compilation unit (and perhaps also with some fancy link-time optimization).

We update the example to put the implementation of get_value inside the compilation unit, and ensure it has no side effects:

int* get_value() {
  return 0;
}

int func() {
  if( get_value() !=NULL)
  {
  }
}

Now, the method is compiled into a no-op:

func():
        rep
        ret

(for the function of that apparently useless rep prefix, see here...)

So it all depends on the details of get_value, and how much the compiler can know about it when it is compiling your empty if statement.

Community
  • 1
  • 1
BeeOnRope
  • 60,350
  • 16
  • 207
  • 386