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]