2012-02-17 81 views
2

编译器会删除这个if语句吗?编译器是否会删除总是评估为零的块?

#define DEBUG 0 
int main(int argc, char ** argv) 
{ 
    if(DEBUG) 
    { 
     ... 
    } 
    return 0; 
} 

我试图谷歌这一点,并搜索计算器,但我想我的搜索词是坏的,因为我无法找到所需的信息。

如果对此进行了优化,我想了解哪些内容以了解优化?

Constantin

+10

您可以通过要求编译器生成其输出的汇编列表来始终找出自己。 – 2012-02-17 22:26:26

+1

取决于你的编译器及其选项,但是它可能会删除整个块。如果它真的添加和删除你需要的代码,尽管我使用#ifdef而不是if来使用条件编译。 – Dampsquid 2012-02-17 22:28:58

+0

只要标准允许编译器执行x或y,就会发现一个编译器执行x,另一个执行y。所以问这样的问题总是只回答:“试试看,看看” – PlasmaHH 2012-02-17 22:33:03

回答

3

我不确定编译器是否可以优化它。我猜是的,因为在这种情况下你不会有任何副作用,所以它可以在不改变代码语义的情况下被安全地删除。

在任何情况下,猜测都不好,依靠优化也不好。

为什么不使用#ifdef .. #endif块代替代码块?

#define DEBUG 

#ifdef DEBUG 
    ... 
#endif 

以这种方式,你将有一个肯定的结果。

+0

我也在考虑这种方法,我只是不想用#ifdef膨胀我的源文件。 (供人阅读)。谢谢杰克。 – Constantin 2012-02-17 22:35:16

+1

我只是通常会将它们与代码一起缩进,以避免有一个不好的视觉方法..但这只是个人品味的问题 – Jack 2012-02-17 22:36:55

3

你不需要猜测。编译并与调试器一起观察汇编指令。您甚至不需要熟悉程序集以查看是否为有问题的行生成了实际的代码。

3

是的,任何像样的C/C++编译器都会删除这样的block。

2

您无法做出通用的说法,即每个编译器都会以相同的方式优化相同的内容。同样,今天可能发生的任何编译器在未来的版本中都可能不会。

是的,今天一些编译器可以并且会这样做,但这并不意味着您应该为此计划或期望它。如果你不想要那些代码,请将其注释掉,如果将其删除或删除。

正如别人所说,尝试一下,找出自己。如果你正在调试某些东西并怀疑这种情况已发生或没有发生,只需查看并找出...

+1

在这种情况下,我认为假设没有工业强度的编译器永远不会失败,优化这一点。但另一方面,DEBUG就是某些人可能会不小心做出一个变量的东西,可以在命令行上进行配置。从这个意义上讲,这可能会很麻烦。 – jkerian 2012-02-17 22:52:00

+0

正确的是,我正在谈论更普遍的“将编译器删除”部分问题太过开放和模糊。调试这个词也会导致使用ide的人不知道使用了哪些命令行选项(包括优化),并且在编译调试时会跳过一些,如果不是所有优化都会跳过,那么您可以单步执行内存监视并像这样的东西。 – 2012-02-17 22:57:52

+0

@dwelch,谢谢你的洞察力。你能否进一步解释你的第二条评论?正在做一个#define DEBUG坏习惯?谢谢。 – Constantin 2012-02-17 23:55:04

1

你有很好的答案来检查它在你的编译程序集输出中。我想有时会有着相似的成语,这是非常有用的对我说:

int main(int argc, char ** argv) 
{ 
    const bool bDebug = false; 
    if(bDebug) 
    { 
     ... 
     LOG(""); /// some heavy loging here 
    } 
    return 0; 
} 

,所以我在我的代码中的一些相关的地方留下这样如果-S,当我得到一个错误报告的东西坏happend我一步通过代码,当我需要输出一些大的数组/数据结构时,我从调试器bDebug变量(实际上我将它们命名为bVerbose)进行修改,然后允许代码输入这样的IF-s。您不必重新编译代码来添加大量日志记录。