【发布时间】:2016-01-12 06:05:18
【问题描述】:
每个程序员都应该知道:
在某些情况下,为了优化程序,编译器可能会修改(!p && !q)为(!(p || q))。
这两个表达式是等价的,计算第一个或第二个没有区别。
但是在 C++ 中,可以重载运算符,并且重载的运算符可能并不总是尊重这个属性。所以以这种方式转换代码实际上会修改代码。
当!、|| 和&& 重载时,编译器是否应该使用德摩根定律?
【问题讨论】:
-
任何理智的编译器编写者都避免相信程序员已经正确地实现了逆运算符。不这样做是一个非常常见的错误。
-
一般来说,如果这些转换不会改变程序的可观察行为(副作用、输出),编译器只能将这些转换应用于您的程序。当
p和q是布尔原语时,当然可以应用德摩根定律,因为这不会改变可观察到的行为。当p和q有重载的运算符时,这可能是也可能不是。 C++ 标准对德摩根定律只字未提。编译器只有在知道它不会改变行为的情况下才被“允许”使用它。 -
如果我在 15 位程序员的办公室里走来走去,让他们中的任何一个说出一条德摩根定律,他们将无法做到。所以“每个程序员都应该知道”的说法有点误导......
-
@corsiKa:“应该”和“将”是两个截然不同的词
-
@corsiKa:每个 C++ 程序员都应该能够,给定代码
if (p || q) { f(); } else { g(); }能够回答“在什么条件下调用g()?”有人可能会说“当(p || q)为假时”,但大多数人可以应用德摩根定理并知道“如果p 或q 为真,则调用f(),当p 和q 都为假时g()”这就是了解规律,即使他们不叫他们的名字。
标签: c++ operator-overloading language-lawyer compiler-optimization