这个表达式 a = a + b - ( b = a );由于C++中的序列点而给出错误的输出
Does this expression a = a + b - ( b = a ); gives wrong output because of sequence point in C++?
参考这个问题。
我已经多次尝试了相同的程序,并且我看到其他人(一群朋友)使用相同的逻辑进行交换,但他们都没有找到错误的输出。我想问一下,由于序列点,是否有可能获得错误的输出。
C++11 不再有序列点,但是是的,该行是未定义的行为,因为b
的修改不是相对于其读取进行排序的。
这意味着任何事情都可能发生;不过,一般来说,主要问题是编译器可能会对事件的确切顺序重新排序。
是的,据我所知,这是未定义的行为。此处的分号是唯一的序列点,因此未定义赋值是在使用相同的变量之前还是之后发生的。
现在,如果你的所有朋友都使用相同的编译器和相同的平台,这似乎很有可能,他们都会看到相同的结果,使用相同的编译器,所以这并不奇怪。这就是这部分问题的答案。
基本上是的。它可能会给出错误的结果,因为在这一行中,B 既是写入的,也是读取的,并且没有指定首先会发生什么。
很可能你已经尝试过很多次了,但你使用相同的编译器,对吧?在这种情况下,您不太可能观察到不同的结果。对于给定的相同代码位,编译器通常会产生稳定的相同结果。
要看到差异,您可能需要更改编译器,或者至少更改一些选项,例如或多或少的激进优化。
这个表达式的问题在于,从理论上讲,它可以编译为:
assign b <- a
a = a + b - a // but now, B is already equal a
或
assign temp1 <- a
assign temp2 <- b
assign b <- a
a = temp1 + temp2 - a // here values are preserved
是的,这是未定义的行为它会给出以下警告
$ g++ -Wall -o test test.cpp test.cpp: 在函数 'int main()' 中: test.cpp:11:21: 警告:"b"上的操作可能未定义 [-W序列点]
如果你使用上面的"技巧"而不是标准的swap
,使用Visual Studio,你会有一个不愉快的惊喜。评估的副作用仍然存在。
C 标准(1999 年版)在第 6.5 节第 2 条中说:
在上一个和下一个序列点之间,对象应通过表达式的计算最多修改一次其存储值。此外,应仅读取先前的值以确定要存储的值。
所以,是的,此代码违反了序列点规则(从中读取b
但不确定b
的新值)。C++从 C 继承了这一点。
- 递归函数计算序列中的平方和(并输出过程)
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 请解释"函数1(p1,p2,p3);"的输出
- 在C++目录中搜索文件的函数输出中出错
- 如果我决定输入 (1 2) 而它要求 x,为什么我的输出会出错,但如果我输入 (12) 工作正常
- 程序的 substr() 函数中的输出出错
- C++ 控制台输出到 cmd 在重复十次后出错
- 使用输出在声明容差范围内的EXPECT_NEAR时出错
- 我同时使用了莱布尼茨和瓦利斯公式来估算π但输出数字错误,我不知道我哪里出错了
- 尝试过载输出运算符时出错
- 输出出错
- C++:将自定义哈希键值从 unordered_map 输出到 std::cout 时出错
- 保护输入和输出文件描述符时出错
- 将字符指针(初始化为"\0")发送到标准输出是否出错?(C++)
- matPutVariable:尝试将数据输出到mat文件时出错(matrix::serialize::WrongSize
- 为什么我的输出流seg出错,而我的虚拟析构函数不起作用,但当我杀死虚拟的时候,它起作用了
- LNK2019输出运算符过载时出错
- 安装用C++编写的Python包(leven)时出错:g++无法识别的命令行选项--输出lib
- 创建输出文件 .rdstate() 时出错,返回值 2
- 在c++中编译Lex输出时出错