【问题标题】:Difference in output of program [duplicate]程序输出的差异[重复]
【发布时间】:2014-05-07 23:48:11
【问题描述】:

我有一个简单的代码 sn-ps,它在使用 C++ 编译器和 C# 编译器构建时显示不同的行为。

C#

static void Main(string[] args)
{
   int i = 0;
   i += i++;
   Console.WriteLine(i);
   Console.ReadLine();
}

i 的结果是0。 从此链接复制。 For i = 0, why is (i += i++) equal to 0?

C++

int main() 
{
    int i = 0;
    i += i++;
    cout << i << endl;
}

i 的结果是1

我只是想知道为什么C#C++的代码输出会有差异。

【问题讨论】:

  • 因为该表达式是未定义的行为。另一个 C++ 编译器(或另一个版本)可能会给出另一个结果。
  • @Adriano:对于 C#,它不是未定义的。
  • 我的猜测是 C++ 首先评估部分“i++”,它是一,然后评估 i+= XXX
  • 因为是两种不同的语言?
  • 这是由于 C# 处理后增量的方式;后自增运算符加一,并返回旧值。如果您将其更改为++i,您将获得您的1 ;-)

标签: c# c++ operator-precedence


【解决方案1】:

在 C 中,像 i= i++; 这样的表达式具有未定义的行为,并且可以计算为 0 或 1(在整个表达式计算之后或赋值之前递增都是可能的)。

这是一个奇怪的设计决定,因为看似无辜且完全合理的代码可能会产生意想不到的结果,例如sum= a[i++] + a[i++];。奇怪的是,似乎没有人在意。

【讨论】:

  • 这是不正确的。后缀 ++ 运算符(例如:i++)具有非常明确的行为。 "++i" 增加 i 并返回新值,"i++" 增加 i 并返回原始值
  • @YvesDubois 但未定义该表达式相对于同一语句中其他(可能引起副作用的)表达式的顺序。
  • 我没有说 ++ 有未定义的行为。我谈到了包含它的表达式。 stackoverflow.com/questions/4176328/…
  • @Servy 计算表达式的顺序非常严格。在给出的两个示例中,结果绝不是不确定的。
  • 由于它是未定义的行为,int i = 0; i = i ++; 甚至可以导致42 结果。或者导致程序崩溃。
【解决方案2】:

C# 和 C++ 的设计者和 C made different decisions about how to handle order of evaluation 而在 C# the order of evaluation 中如果从左到右:

表达式中的操作数从左到右计算。

副作用也从左到右发生。

在 C++ 中情况并非如此,draft C++ standard 部分 1.9 程序执行 段落 15 说:

除非另有说明,否则单个运算符的操作数和单个表达式的子表达式的求值是无序的。

如果对同一个标量对象的副作用相对于另一个副作用进行排序,则结果undefined behavior

[...]如果标量对象的副作用相对于同一标量对象的另一个副作用或使用同一标量对象的值的值计算是未排序的,则行为未定义。 [.. .]

草案给出了未定义行为的示例:

i = i++ + 1; // the behavior is undefined

如果我们从您的代码中查看表达式:

i += i++;

相当于:

i = i + i++ ;

我们现在可以清楚地看到它调用了未定义的行为,这意味着结果是不可预测的并且不能依赖。

【讨论】:

猜你喜欢
  • 2017-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 2020-09-28
  • 1970-01-01
相关资源
最近更新 更多