繁体   English   中英

如果在c程序中编译0

[英]if 0 is compiled in c program

我正在尝试从我的程序中删除未使用的代码 - 我现在无法删除代码,我只想暂停它。

假设我有以下代码:

if (cond){
  doSomething()
}

cond总是假的所以doSomething永远不会被称为。

我想做的事情如下:

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

现在,对于我们(并且希望编译器)这个代码未被使用是显而易见的。

编译器if会删除所有这些条件,否则它将离开它并且永远不会进入?

PS:我不能将#if 0用于此目的

GCC将显式删除具有控制它们的常量表达式的条件块,并且GNU编码标准明确建议您利用这一点 ,而不是使用诸如依赖预处理器之类的更粗糙的方法。 尽管使用预处理器#if可能看起来更有效,因为它在早期阶段删除了代码,但在实践中,现代优化器在为您提供尽可能多的信息时效果最佳(当然,如果您可以避免添加,它会使您的程序更清晰,更一致在不必要的点处的相分离依赖性)。

对于现代编译器来说,像这样的决策非常非常容易 - 即使非常简单的TCC也会执行一些死代码消除; LLVM和GCC这样强大的系统会发现这一点,以及你作为人类读者可能会错过的更复杂的情况(通过跟踪变量的生命周期和修改,而不仅仅是单点查看)。

这是除了全编译的其他优势,如一个事实,即在你的代码if将错误检查(而#if是删除代码,这将是你当前系统上的错误,比如不存在的平台功能引用的更多有用)。

尝试

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

代替。 别忘了做一个

#define REMOVE_UNUSED_CODE

某处。

答案取决于编译器的实现。 你永远不应该依赖于此。

而是明确:

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

看看你的代码片段

#define REMOVE_UNUSED_CODE 0

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

编译前, REMOVE_UNUSED_CODE由预处理器替换为0 因此, if(cond && 0)将始终被评估为false并且永远不会被执行。 所以你可以说,无论cond是什么,它总是假的。

所以我宁愿这样做:

//#define REMOVE_UNUSED_CODE 0

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

你不应该这样做:

假设你有一个带副作用的函数bool f(void* input)

然后用

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

身体不评价,但f应该的。

如果是

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

由于&&运算符的快捷方式规则,因此不评估f。

如果你使用

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

#endif

整个代码甚至没有编译,永远不会被执行。

不是直接的答案,但可能会有所帮助。 有特定于编译器的内在函数来执行代码删除。

对于MSVC,它是__assume(0)

对于GCC / Clang,它是__builtin_unreachable()

但请注意,如果你写的东西如下:

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

你的病情永远不应该评估为true ,否则行为是不确定的。 && REMOVE_UNUSED_CODE__builtin_unreachable()组合在一起可确保编译器删除您的代码。

暂无
暂无

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

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