[英]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.