If 0 is compiled in a c program
I am trying to remove unused code from my program - I cannot remove the code at the moment, I just want to disable it to begin with.
Let's say that I have the following code:
if (cond){
doSomething()
}
and is cond
always false, so it is doSomething
never called.
I want to do something like:
#define REMOVE_UNUSED_CODE 0
if (cond && REMOVE_UNUSED_CODE){
doSomething()
}
It is now obvious to us (and hopefully to the compiler) that this code is not being used.
Will the compiler remove this whole condition if
or will it leave it and not enter?
PS: I cannot use #if 0
for this purpose
source to share
GCC will explicitly remove conditional blocks with a constant expression controlling them, and the GNU coding standards explicitly recommend that you take advantage of this instead of using crude methods such as using a preprocessor. While using a preprocessor #if
may seem more efficient because it removes code earlier, in practice modern optimizers work best when you provide them with as much information as possible (and of course it makes your program cleaner and more consistent if you can avoid adding a phase separation dependency at a point where it is not necessary).
Solutions like this are very easy for a modern compiler - even a very simplistic TCC will do some dead code removal; powerful systems like LLVM and GCC will detect this, as well as much more complicated cases that you as a human reader can skip (by tracking the lifetime and modifying variables, other than just looking at individual points).
This is in addition to other benefits of full compilation, such as the fact that your code if
will be checked for errors (whereas it is #if
more useful for removing code that would be erroneous on your current system, like references to non-existent platform functions).
source to share
Looking at this piece of code
#define REMOVE_UNUSED_CODE 0
if(cond && REMOVE_UNUSED_CODE)
{
doSomething();
}
REMOVE_UNUSED_CODE
replaced by a 0
preprocessor before compilation. Therefore, if(cond && 0)
it will always evaluate to false and will never execute. So you can tell, no matter what cond
, it will always be false.
So I would prefer it to be done like this:
//#define REMOVE_UNUSED_CODE 0
#ifdef REMOVE_UNUSED_CODE
if(cond)
{
doSomething();
}
#endif
source to share
You shouldn't be doing this:
Let's say you have a function bool f(void* input)
with side effects.
Then with
if( f(pointer) && false ) { ... }
the body is not evaluated, but it f
should be.
When
if( false && f(pointer) ) { ... }
f is not evaluated due to the operator short-circuiting rule &&
.
If you are using
#define REMOVE_UNUSED_CODE
#ifndef REMOVE_UNUSED_CODE
if( f(pointer) && false ) { }
#endif
all the code doesn't even compile and will never be executed.
source to share
Not a direct answer, but might be helpful. There are compiler-specific functions for removing code.
For MSVC it is __assume(0)
For GCC / Clang, this is __builtin_unreachable()
.
Note that if you write something like:
if (cond){
__builtin_unreachable();
doSomething()
}
Your state should never be evaluated as true
, otherwise the behavior is undefined. Combining both && REMOVE_UNUSED_CODE
will __builtin_unreachable()
ensure that your code is removed by the compiler.
source to share