1

为了评估乘法,您必须评估第一项,然后是第二项,最后将这两个值相乘。

假设每个数字乘以 0 都是 0,如果第一项的评估返回 0,我希望整个乘法被评估为 0,而不评估第二项。

但是,如果您尝试此代码:

var x = 0 * ComplexOperation();

尽管我们知道 x 为 0,但仍调用函数 ComplexOperation。

优化的行为也将与仅在第一项被评估为真时才评估第二项的布尔运算符“&&”一致。('&' 运算符在任何情况下都会评估这两个术语)

我测试了这种行为,C#但我想几乎所有语言都是一样的。

4

4 回答 4

15

首先,对于浮点,您的断言甚至不正确!考虑0 * inf不是 0,0 * nan也不是 0。

但更一般地说,如果你在谈论优化,那么我猜编译器可以自由地不评估ComplexOperation它是否可以证明没有副作用。

但是,我认为您实际上是在谈论短路语义(即语言功能,而不是编译器功能)。如果是这样,那么真正的理由是 C# 正在复制早期语言(最初是 C)的语义以保持一致性。

于 2013-01-31T16:33:29.240 回答
6

C# 不是函数式的,因此函数可能会产生副作用。例如,您可以从内部打印某些内容ComlpexOperation或更改全局静态变量。所以,是否被调用是由*合约定义的。

&您发现自己是与和的不同合同的示例&&

于 2013-01-31T16:37:51.263 回答
3

该语言定义了哪些运算符具有短路语义,哪些没有。你的ComplexOperation函数可能有副作用,这些副作用可能是故意的,编译器不能自由地假设它们不应该仅仅因为函数的结果没有被有效地使用而发生。

于 2013-01-31T16:36:45.150 回答
2

我还将添加这将是混淆的语言设计。会有很多这样的问题...

//why is foo only called 9 times?????????
for(int i = 0; i < 10; i++) {
    print((i-5)*foo());
}

为什么允许短路布尔值而不是短路0*?好吧,首先我要说的是,将短路布尔值与副作用混合是代码中错误的常见来源 - 如果在将其理解为明显模式的维护者中使用得当,那么它可能没问题,但对我来说很难想象一下,程序员已经习惯了整数中的 0 洞。

于 2013-01-31T16:36:24.930 回答