Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiler: What if condition is always true / false

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.

like image 473
Martin Pohorský Avatar asked Aug 19 '16 08:08

Martin Pohorský


2 Answers

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.

like image 68
Lundin Avatar answered Oct 31 '22 17:10

Lundin


The code you wrote should never be executed, however, it could be available in the executable.

I would say that the compiler would be required on keeping this code when you would disable optimizations (like adding -O0 to Clang and GCC). In all other cases, I would hope that the compiler would remove the code as this is a very simple optimization with a remarkable code size effect. For instance, GCC eliminates this at -O and higher. (See the manual)

Though, there are 2 other ways of writing your code, which will enforce this code to not be included:

  • Preprocessor conditionals
  • constexpr if

By making use of the preprocessor conditionals, you will be able to remove the code before it reaches the actual compiler. It might be a bit intrusive for your indenting, though it will work with all compilers and versions from the C and C++ standards.

#ifdef DEBUG
   { // Optional: Adding extra scope to prevent usage of local variables after the endif
   // Code to eliminate
   }
#endif

However, if you are using C++17, you could also use constexpr if. This will be less intrusive in your code and although the code in the if-statement has to be syntactic correct, it doesn't have to compile (so not semantically correct).

This can be written as:

if constexpr (DEBUG)
{
    // Code to eliminate
}
like image 1
JVApen Avatar answered Oct 31 '22 18:10

JVApen