简体   繁体   English

如果在c程序中编译0

[英]if 0 is compiled in c program

I'm trying to removed unused code from my program - I can't delete the code for now, I just want to disable it for a start. 我正在尝试从我的程序中删除未使用的代码 - 我现在无法删除代码,我只想暂停它。

Let's say that I have the following code: 假设我有以下代码:

if (cond){
  doSomething()
}

and cond is always false so doSomething is never called. cond总是假的所以doSomething永远不会被称为。

I want to do something like: 我想做的事情如下:

#define REMOVE_UNUSED_CODE 0
if (cond && REMOVE_UNUSED_CODE){
  doSomething()
}

Now this is obvious to us (and hopefully for the compiler) that this code is unused. 现在,对于我们(并且希望编译器)这个代码未被使用是显而易见的。

Will the compiler remove all this if condition or it will leave it and never get in? 编译器if会删除所有这些条件,否则它将离开它并且永远不会进入?

PS: I can't use #if 0 for this purpose PS:我不能将#if 0用于此目的

GCC will explicitly remove conditional blocks that have a constant expression controlling them, and the GNU coding standards explicitly recommend that you take advantage of this , instead of using cruder methods such as relying on the preprocessor. GCC将显式删除具有控制它们的常量表达式的条件块,并且GNU编码标准明确建议您利用这一点 ,而不是使用诸如依赖预处理器之类的更粗糙的方法。 Although using preprocessor #if may seem more efficient because it removes code at an earlier stage, in practice modern optimizers work best when you give them 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 isn't necessary). 尽管使用预处理器#if可能看起来更有效,因为它在早期阶段删除了代码,但在实践中,现代优化器在为您提供尽可能多的信息时效果最佳(当然,如果您可以避免添加,它会使您的程序更清晰,更一致在不必要的点处的相分离依赖性)。

Decisions like this are very, very easy for a modern compiler to make - even the very simplistic TCC will perform some amount of dead-code elimination; 对于现代编译器来说,像这样的决策非常非常容易 - 即使非常简单的TCC也会执行一些死代码消除; powerful systems like LLVM and GCC will spot this, and also much more complex cases that you, as a human reader, might miss (by tracing the lifetime and modification of variables beyond simply looking at single points). LLVM和GCC这样强大的系统会发现这一点,以及你作为人类读者可能会错过的更复杂的情况(通过跟踪变量的生命周期和修改,而不仅仅是单点查看)。

This is in addition to other advantages of full compilation, like the fact that your code within the if will be checked for errors (whereas #if is more useful for removing code that would be erroneous on your current system, like references to nonexistent platform functions). 这是除了全编译的其他优势,如一个事实,即在你的代码if将错误检查(而#if是删除代码,这将是你当前系统上的错误,比如不存在的平台功能引用的更多有用)。

Try 尝试

#ifndef REMOVE_UNUSED_CODE
if (cond) {
   doSomething();
}
#endif

Instead. 代替。 Don't forget to do a 别忘了做一个

#define REMOVE_UNUSED_CODE

somewhere. 某处。

The answer depends on the implementation of the compiler. 答案取决于编译器的实现。 You should never depend on this. 你永远不应该依赖于此。

Instead be explicit: 而是明确:

#define REMOVE_UNUSED_CODE 0
if (cond && REMOVE_UNUSED_CODE){
#ifndef REMOVE_UNUSED_CODE  
   doSomething()
#endif
}

Looking at this snippet of your code 看看你的代码片段

#define REMOVE_UNUSED_CODE 0

if(cond && REMOVE_UNUSED_CODE)
{
    doSomething();
}

REMOVE_UNUSED_CODE is replaced with 0 by preprocessor before compilation. 编译前, REMOVE_UNUSED_CODE由预处理器替换为0 So if(cond && 0) will always be evaluated as false and will never be executed. 因此, if(cond && 0)将始终被评估为false并且永远不会被执行。 So you can say, irrespective of what cond is, it will always be false. 所以你可以说,无论cond是什么,它总是假的。

So I'd rather prefer it doing this way: 所以我宁愿这样做:

//#define REMOVE_UNUSED_CODE 0

#ifdef REMOVE_UNUSED_CODE
    if(cond)
    {
        doSomething();
    }
#endif

You should not do it that way: 你不应该这样做:

Suppose you have a function bool f(void* input) with side effects. 假设你有一个带副作用的函数bool f(void* input)

Then with 然后用

if( f(pointer) && false ) { ... }

the body is not evaluated, but f should be. 身体不评价,但f应该的。

In the case of 如果是

if( false && f(pointer) ) { ... }

f is not evaluated because of the short-cut rule of the && operator. 由于&&运算符的快捷方式规则,因此不评估f。

If you use 如果你使用

#define REMOVE_UNUSED_CODE
#ifndef REMOVE_UNUSED_CODE
if( f(pointer) && false ) { }

#endif

the whole code is not even compiled in and will never be executed. 整个代码甚至没有编译,永远不会被执行。

Not a direct answer, but may be helpful. 不是直接的答案,但可能会有所帮助。 There are compiler-specific intrinsics to do code removal. 有特定于编译器的内在函数来执行代码删除。

For MSVC, it is __assume(0) 对于MSVC,它是__assume(0)

For GCC/Clang, it is __builtin_unreachable() . 对于GCC / Clang,它是__builtin_unreachable()

Notice, however, that if you write something like: 但请注意,如果你写的东西如下:

if (cond){
  __builtin_unreachable();
  doSomething()
}

Your condition should never evaluate to true , otherwise behavior is undefined. 你的病情永远不应该评估为true ,否则行为是不确定的。 Combining both && REMOVE_UNUSED_CODE and __builtin_unreachable() ensures that your code will be removed by the compiler. && REMOVE_UNUSED_CODE__builtin_unreachable()组合在一起可确保编译器删除您的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM