【问题标题】:In C++ and C# are multiple condition checks performed in a predetermined or random sequence?在 C++ 和 C# 中,多个条件检查是按预定顺序还是随机顺序执行的?
【发布时间】:2010-10-24 15:31:00
【问题描述】:

情况:在 C++ 或 C# 中使用许多条件检查条件:

if (condition1 && condition2 && condition3)
{
    // Do something
}

我一直认为这些检查的执行顺序并不能保证。所以不一定是第一个条件1,然后是条件2,然后才是条件3。我在使用 C++ 的时候就学会了它。我想我是被告知或在某处读到的。

直到知道我一直编写安全代码来解决以下情况下可能出现的空指针:

if ((object != null) && (object.SomeFunc() != value))
{
    // A bad way of checking (or so I thought)
}

所以我在写:

if (object != null)
{
    if (object.SomeFunc() != value)
    {
        // A much better and safer way
    }
}

因为我不确定非空检查是否会首先运行,然后才会调用实例方法来执行第二次检查。

现在,我们最伟大的社区人士告诉我,这些检查的执行顺序保证按照从左到右的顺序运行。

我很惊讶。 C++ 和 C# 语言都是这样吗?

现在有人听过我以前听过的版本吗?

【问题讨论】:

  • C# 中的子表达式从左到右计算,始终是句点。 C/C++ 中的子表达式按序列点顺序计算。同一序列点中的两个表达式可以按任意顺序求值。如果您需要正式的定义,请在“序列点”上进行网络搜索。

标签: c# c++ deterministic non-deterministic


【解决方案1】:

短答案从左到右进行短路评估。顺序是可预测的。

// perfectly legal and quite a standard way to express in C++/C#
if( x != null && x.Count > 0 ) ...

有些语言在分支之前评估条件中的所有内容(例如 VB6)。

// will fail in VB6 if x is Nothing. 
If x Is Not Nothing And x.Count > 0 Then ...

参考:MSDN C# Operators 及其顺序或优先级。

【讨论】:

  • @Robert:你不是说“如果 x 不是 Nothing && ...”(或等效的 VB6 语法)吗?
  • @RichieHindle - 是的,我对 VB6/VBScript 的回忆非常古老。我会更新
【解决方案2】:

它们必须从左到右进行。这允许短路评估工作。

请参阅Wikipedia article 了解更多信息。

【讨论】:

    【解决方案3】:

    我认为没有或曾经有任何其他方式。这就像编译器决定无缘无故地乱序运行语句。 :) 现在,某些语言(如 VB.NET)具有用于短路和不短路的不同逻辑运算符。但是,顺序总是在编译时明确定义的。

    这是来自 C# 语言规范的operator precedence。从规范...

    除了赋值运算符, 所有二元运算符都是 左联想,意思是 操作从左到右执行 正确的。例如,x + y + z 是 计算为 (x + y) + z。

    【讨论】:

    • 再一次,子表达式求值的优先级、关联性和顺序是三个不同的东西。您无法在 C# 中根据优先级确定顺序。
    • 另外,我很遗憾您引用的那段规范措辞不佳。我一直在努力解决这个问题。
    • 是的,我明白你的意思。这是违反直觉的,但我认为该操作可以是左关联的,并且仍然可以按照从左到右的顺序进行评估。两者都需要在应用操作之前进行评估,因此优先级不一定意味着评估顺序。但是你将不得不放弃短路,因为短路 && 不会(必然)使用两个运算符和三个操作数和 ||短路不适用于两个。
    【解决方案4】:

    它们被定义为从左到右进行评估,在其中一个评估为假时停止评估。在 C++ 和 C# 中都是如此。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-09
      • 1970-01-01
      • 2020-02-10
      • 2022-01-02
      • 2016-10-10
      • 1970-01-01
      • 1970-01-01
      • 2012-10-24
      相关资源
      最近更新 更多