Compiler optimization of if statements where the condition is always true/false
Asked Answered
V

2

14

I think about conditionals and compilers. I am programming an application for Arduino and so I need the application to be as fast as possible.

In my code I have this:

#define DEBUG false    

...

if (DEBUG)
{
  String pinName;
  pinName = "Pin ";
  pinName += pin;
  pinName += " initialized";
  Serial.println(pinName);
}

I am wondering if the compiler does not include the code (code in if block) in binary file. The conditions is always false, so the program never goes there.

And from the other side. What if DEBUG is true? Does Arduino test the condition or the compiler include only the body of if in binary file?

I found this site https://gcc.gnu.org/onlinedocs/gcc-3.0.2/cpp_4.html about #if directive, so I can rewrite the code to have these directives instead of "normal" if. But I would like to know if I should rewrite it or if it would be waste of time.

Veranda answered 19/8, 2016 at 8:34 Comment(6)
A smart compiler will do the optimization and will not include the code in binary if DEBUG is false.Sines
if (CONSTANT) { ... } is very easy for a compiler to optimize. I would expect that any decent compiler from at least the last 25 years should be able to remove the conditional branch.Pesek
I'd use #if/#endif, even if it doesn't make a difference in the binary. That way it's clear what DEBUG is.Albigenses
@LogicStuff: It is a bad idea to use #if/#endif because the compiler will not check the code if the condition is false. We know that any real world compiler will optimize the code out as with #if/#endif I tend to use not macro stuff!Binoculars
I need the application to be as fast as possible. -- write it in assembly not in C/C++.Mutable
@AleksanderZ.Okay, nice comment. But I also need WiFi control and HTTP communication. And I would like to finish it in this life span :).Washedup
D
11

Any half-decent optimizing compiler will remove the whole code inside the if statement, if it can tell at compile-time that the condition always evaluates to false. Similarly, any half-decent compiler would skip the check itself if the condition is always true.

Indeed this is completely equivalent to "compiler switches" such as:

#define DEBUG


#ifdef DEBUG
...
#endif

The "compiler switch" syntax with #ifdef is to prefer, as it makes the intent clearer to other C programmers. But that's just a matter of coding style - it will result in the same binary as your original code.

Disrespectful answered 19/8, 2016 at 8:59 Comment(2)
Related: en.wikipedia.org/wiki/Dead-code_elimination - gcc will do it even at -O0 (debug builds) for conditions like if (0) so even the debug-build behaviour of not optimizing across statements doesn't stop the compiler from seeing a compile-time-constant value as the controlling expression. Can I safely assume that if(true) and if(false) will be optimized? . Others like MSVC will only do dead code removal if optimization is enabled; in debug builds it'll actually mov a constant into a register and cmp against another constant.Caffeine
How to ensure some code is optimized away? suggests if constexpr(DEBUG) for C++17.Caffeine
V
0

I do not like answering my own question, because I would not figure it out without your help, guys.

Anyway, first option is to use:

#if DEBUG == true
#endif

or

#ifdef DEBUG
#endif

the compiler does not get the code in #if / #ifdef (preprocessor removes it), so if there is a problem in this part of code, no one would know about it if DEBUG is set to false or is not defined at all (thanks @Klaus).

Second option:

#define DEBUG false    

...

if (DEBUG)
{
  ...
}

Any newer compiler should remove the 'if' block if the condition is false or remove the 'if' statement and leave body if the condition is true.

So I would say it is on programmer which approach suites better the needs of application.

The first approach is better if you need to be sure the code would not be included in binary.

The second approach is better if you want the compiler to check the whole code each time you compile the program.

If you like this answer, vote for it and I will accept it - if no one provides a better one.

Veranda answered 19/8, 2016 at 11:4 Comment(1)
#if DEBUG == true can be replaced with #if DEBUG. The other option is #ifdef DEBUG. For some definitions like library options you can use #if style, but specifically for DEBUG it is better to use #ifdef syntax.Cullender

© 2022 - 2024 — McMap. All rights reserved.