C++ c++;11评估顺序(未定义的行为) vec[ival++]

C++ c++;11评估顺序(未定义的行为) vec[ival++],c++,c++11,undefined-behavior,C++,C++11,Undefined Behavior,它避免了未定义的行为,因为您没有更改ival的值。您在第一个示例中看到的问题是,我们无法确定使用ival时的值。在第二个示例中,没有混淆。让我们先从最糟糕的问题开始,那就是未定义的行为。C++使用排序规则。语句按顺序执行。通常这是自上而下的,但是if语句、for语句、函数调用等可以改变这一点 现在有了一个语句,可能还会有进一步的执行顺序,但我非常有意地编写了may。默认情况下,单个语句的各个部分不会相对彼此排序。这就是为什么你可以得到不同的执行顺序。但更糟糕的是,如果您更改并使用单个对象而不进行

它避免了未定义的行为,因为您没有更改
ival
的值。您在第一个示例中看到的问题是,我们无法确定使用
ival
时的值。在第二个示例中,没有混淆。

让我们先从最糟糕的问题开始,那就是未定义的行为。C++使用排序规则。语句按顺序执行。通常这是自上而下的,但是
if
语句、
for
语句、函数调用等可以改变这一点

现在有了一个语句,可能还会有进一步的执行顺序,但我非常有意地编写了may。默认情况下,单个语句的各个部分不会相对彼此排序。这就是为什么你可以得到不同的执行顺序。但更糟糕的是,如果您更改并使用单个对象而不进行排序,则会出现未定义的行为。这很糟糕,任何事情都有可能发生

建议的解决方案(
iVal+1
)不再更改
iVal
,而是生成一个新值。这是完全安全的。尽管如此,它仍然保持了
iVal
不变


您可能需要检查
std::nexting\u find()
。您尝试编写的循环可能已经在标准库中。

是的,您的第一个示例具有未定义的行为,因为我们对内存位置进行了未排序的修改和访问,这是未定义的行为。这是在C++标准(强调矿山)中的:

除非另有说明,否则对单个运算符的操作数进行求值 单个表达式的子表达式的和未排序。 [ 注意:在执行过程中多次求值的表达式中 程序的执行,未排序和不确定排序 其子表达式的求值不需要一致地执行 在不同的评价中- 尾注 ] 系统的价值计算 运算符的操作数在计算 运算符的结果。如果对内存位置有副作用 ([intro.memory])相对于另一个副作用是不排序的 在同一内存位置或使用 同一内存位置中的任何对象,并且它们不可能 并发([intro.multithread]),行为未定义[ 注: 下一款规定了类似但更复杂的限制 潜在的并发计算- 尾注 ] [ 例如:

vec[ival] <= vec[ival + 1]
- 结束示例 ]


如果检查关系运算符的覆盖部分<>代码> p>第一个问题是,当初始代码显示未定义的行为时,在C++标准下没有“修复”。该代码行的行为没有由C++标准指定;要知道它应该做什么,必须有另一个信息源。

正式地,该表达式可以改写为<代码>系统(“格式C:”)< /C>,因为C++标准不授权来自显示未定义行为的程序的任何行为。 但在实践中,当你遇到类似的事情时,你必须了解原始程序员的想法

嗯,你可以用lambdas解决任何问题

void g(int i) {
  i = 7, i++, i++;              // i becomes 9

  i = i++ + 1;                  // the value of i is incremented
  i = i++ + i;                  // the behavior is undefined
  i = i + 1;                    // the value of i is incremented
}

[&]{bool ret=vec[ival]您在这里遗漏了两个概念。计算顺序未指定。但是,未指定的行为仍然受到语言允许的限制。在这里,只有有限数量的顺序,而实际的顺序必须是其中之一。未定义的行为更糟糕。语言对此没有任何限制。顺便问一下,您是否选择了随机数M C++版本,或者你具体是指两个版本的C++版本。@ MsAlter我讨厌某些问题没有特定的原因被用语言或工具的版本标记。版本标签仍然有用,但是它们需要被用于一个明确的原因。对同一内存位置的影响和读取。使用C++11可以有未指定的求值顺序,但没有未定义的行为@MSalters即使现在也不太疯狂。如果
ival
是一个正常的整数类型,我认为没有lambdas,也可以通过
(++ival,vec[ival-1]实现相同的行为@supercat以使用
操作符为代价,这对我来说太远了
void g(int i) {
  i = 7, i++, i++;              // i becomes 9

  i = i++ + 1;                  // the value of i is incremented
  i = i++ + i;                  // the behavior is undefined
  i = i + 1;                    // the value of i is incremented
}
[&]{ bool ret = vec[ival] <= vec[ival+1]; ++ival; return ret; }()
vec[ival] <= vec[ival+1]