编译器可以根据assert(...)表达式/契约进行优化吗?

时间:2013-08-12 19:52:00

标签: compiler-optimization d

http://dlang.org/expression.html#AssertExpression

关于assert(0):“编译的优化和代码生成阶段可能会认为它是无法访问的代码。”

相同的文档声明assert(0)是一个'特殊情况',但有几个原因可以追随。

D编译器能否根据合同和其他地方的一般assert - 离子进行优化?

(好像我需要享受in{}out{}构造的另一个原因,但它肯定会让我感到更加头晕要知道写这些东西可能会让事情发生变化。

2 个答案:

答案 0 :(得分:4)

理论上,是的,在实践中,我认为它不会,特别是因为断言在dmd -release上进入优化器之前被杀死了。我不确定gdc和ldc,但我认为他们分享了这部分代码。

规范的特殊情况参考btw是断言(0)仍然以某种形式存在-release编译标志。它被转换为非法指令(asm {hlt;} - x86上的非内核程序不允许使用它,所以它会在命中时出现段错误),而所有其他的断言完全被排除在代码之外 - 发布模式。

答案 1 :(得分:1)

GDC肯定会根据断言进行优化。 if条件可以产生更好的代码,甚至会导致不必要的代码消失。然而,遗憾的是,它实现的方式是整个断言可以在发布构建模式中消失,因此编译器永远不会看到有益的if条件信息,并且实际上在发布中生成的代码比在调试模式下更差!具有讽刺意味的。我不得不承认,我只是在 body 中的断言条件中查看了这个效果,我还没有检查进出块的效果。可以基于命令行开关iirc关闭in-out-etc合约块,因此它们甚至不编译,我认为这可能意味着编译器甚至不会查看它们。所以这是可能影响代码生成的另一件事,我没有看过它。但是这里有一个特性,我非常希望看到断言条件中的if条件真值(检查断言cond的表达式中没有副作用代码)总是可以注入到编译器中作为一个假设,就好像即使在发布模式下也有if语句。这将涉及假装你刚刚看到if(xxx),但是在发布模式下抑制了测试的实际代码生成,并且后续代码感觉到已知真值,值范围限制等的有益效果。 / p>