这是未指定(未定义的)行为
Is this unspecified (undefined) behaviour or not?
我已经阅读了本文:未定义的行为和序列点,但我无法弄清楚它是否是ub。
考虑,以下示例:
#include <iostream>
class op {
public:
explicit op(int x) {
std::cout << "x: " << x << std::endl;
}
op & operator + (const op & /* other */) {
return *this;
}
};
int main(int /* argc */, char * /* argv */ []) {
int x = 0;
op o = op(x++) + op(x++) + op(x++);
std::cout << "res: " << x << std::endl;
return 0;
}
我期望这样的输出(或根据评估顺序取消输出的某些输出):
x: 0
x: 1
x: 2
res: 3
GCC-4.7.1和Clang-3.0给我这样的输出,但是当我使用MSVC-2010编译此示例时,我已经输出了:
x: 0
x: 0
x: 0
res: 3
您可以给我一些有关此行为的信息。
a + b + c
中参数评估的顺序是编译器特定的。因此,拨打x++
的呼叫顺序将是特定于编译器的,并且中继将是未定义的行为。
在此类表达式中使用x++
或++x
通常是不良编码标准的迹象。最好避免它并简化您的表达方式。
在此问题编译器和C 评估的论点顺序中,您可以在C 中找到有关参数评估顺序的讨论。
这是C 评估顺序的解释,其中包括C 标准的引用:http://en.cppreference.com/w/cpp/language/eval_order
p.s。 bjarne stroustrup在" C 编程语言"中明确表示,第3版第6.2.2节。他还提供了一个原因:
在没有表达评估顺序的限制的情况下,可以生成更好的代码。
(来自https://stackoverflow.com/a/2934909/1065190)
它是未定义的行为,因为 x
的后插图之间没有序列。您无法判断哪个+
将首先评估,您无法首先构建哪个op(x++)
,也无法确定将执行x++
的顺序。它是不确定的,只是不要写那样的代码。
相关文章:
- 不知道某个东西是否被忽略会引入未定义的行为吗
- c++11评估顺序(未定义的行为)
- 此增量后语句是否会导致未定义的行为?
- 这个失败的测试是将零添加到空指针未定义的行为、编译器错误还是其他什么?
- 为什么从 char 转换为 std::byte 可能是未定义的行为?
- 删除[]具有不同类型的未定义行为?
- 为什么 setjmp/longjmp 的这种用法是未定义的行为?
- CPP 程序中未定义的行为
- 引用释放的内存是未定义的行为吗?
- vector.push_back(vector.back()+1) 是未定义的行为吗?
- 在销毁期间从另一个线程调用对象上调用方法是否未定义行为?
- 从 std::string 到 std::array<char,size> 的 memcopy 额外数据是否是一种未定义的行为?
- 具体来说,标准在哪里规定修改 const 对象是未定义的行为?
- 将结构 std::memcpy 转换为具有足够容量的 std::vector 是未定义的行为<char>吗?
- 为什么销毁被放置 new 覆盖的对象不是未定义的行为?
- 在硬件SIMD矢量指针和相应类型之间进行"interpret_cast"是一种未定义的行为吗
- std::rethrow_exception(nullptr) 未定义的行为还是bad_exception?
- 计算地址差异是未定义的行为吗?
- FlatBuffers C++ reinterpret_cast访问实际上是未定义的行为吗?这样做实际上可以吗?
- 负指数是否必然意味着未定义的行为