我正在尝试从我的程序中删除未使用的代码 - 我现在无法删除代码,我只想暂停它。
假设我有以下代码:
if (cond){
doSomething()
}
且cond
始终为false,因此永远不会调用doSomething
。
我想做类似的事情:
#define REMOVE_UNUSED_CODE 0
if (cond && REMOVE_UNUSED_CODE){
doSomething()
}
现在这对我们来说是显而易见的(并且希望对编译器而言)这段代码是未使用的。
编译器是否会删除所有这些if
条件,否则它会离开它并且永远不会进入?
P.S。:我不能将#if 0
用于此目的
答案 0 :(得分:3)
GCC将显式删除具有控制它们的常量表达式的条件块,以及the GNU coding standards explicitly recommend that you take advantage of this,而不是使用诸如依赖预处理器之类的粗糙方法。虽然使用预处理器#if
可能看起来更有效,因为它在早期阶段删除了代码,但实际上,现代优化器在为您提供尽可能多的信息时效果最好(当然,如果您使程序更清晰且更一致可以避免在不必要的地方添加相分离依赖性。
这样的决策对于现代编译器而言非常容易非常 - 即使非常简单的TCC也会执行一些死代码消除;像LLVM和GCC这样强大的系统会发现这一点,以及你作为人类读者可能会错过的更复杂的案例(通过追踪变量的生命周期和修改,而不仅仅是单点查看)。
这是完全编译的其他优点之外的事实,例如if
中的代码将被检查错误(而#if
对于删除会删除的代码更有用在当前系统上是错误的,比如对不存在的平台功能的引用。)
答案 1 :(得分:2)
尝试
#ifndef REMOVE_UNUSED_CODE
if (cond) {
doSomething();
}
#endif
相反。 别忘了做
#define REMOVE_UNUSED_CODE
的某个地方。
答案 2 :(得分:1)
答案取决于编译器的实现。你永远不应该依赖于此。
相反明确:
#define REMOVE_UNUSED_CODE 0
if (cond && REMOVE_UNUSED_CODE){
#ifndef REMOVE_UNUSED_CODE
doSomething()
#endif
}
答案 3 :(得分:0)
查看代码片段
#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
答案 4 :(得分:0)
你不应该这样做:
假设您有一个带副作用的函数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
整个代码甚至没有编译,也永远不会被执行。
答案 5 :(得分:0)
不是直接的答案,但可能会有所帮助。有特定于编译器的内在函数可以删除代码。
对于MSVC,它是__assume(0)
对于GCC / Clang,它是__builtin_unreachable()
。
但是,请注意,如果您写的内容如下:
if (cond){
__builtin_unreachable();
doSomething()
}
您的情况永远不应评估为true
,否则行为未定义。
结合&& REMOVE_UNUSED_CODE
和__builtin_unreachable()
可确保编译器删除您的代码。