为什么表达式 a = a + b - ( b = a ) 在 c++ 中给出序列点警告?
Why does the expression a = a + b - ( b = a ) give a sequence point warning in c++?
以下是测试代码:
int main()
{
int a = 3;
int b = 4;
a = a + b - (b = a);
cout << "a :" << a << " " << "b :" << b << "n";
return 0;
}
编译此选项会给出以下警告:
> $ g++ -Wall -o test test.cpp test.cpp: In function ‘int main()’:
> test.cpp:11:21: warning: operation on ‘b’ may be undefined
> [-Wsequence-point]
为什么操作可以未定义?
根据我的理解,首先应该计算子表达式(b = a)
,因为 () 的优先级更高,因此设置 b = a。然后,由于"+"和"-"具有相同的优先级,因此表达式将以左关联方式计算。因此,接下来应该评估a + b
,最后从a + b
中减去(b = a)
的结果。我在这里看不到任何违反的序列点规则。
正在计算的表达式和完成其副作用之间存在差异。
由于括号的优先级较高,b = a
赋值表达式将在减法之前计算。它将提供作为评估结果的a
值。但是,将该值写入b
可能要到下一个序列点才能完成,在这种情况下,这是完整表达式的结尾。因此,整体表达式的最终结果是不确定的,因为减法可能会在赋值之前或之后取b
的值。
在C++中,算术表达式中的子表达式没有时间顺序。
a = x + y;
x
是先评估还是y
? 编译器可以选择其中之一,也可以选择完全不同的内容。 计算顺序与运算符优先级不同:运算符优先级是严格定义的,并且评估顺序仅定义为程序具有序列点的粒度。
事实上,在某些体系结构上,可以发出同时评估x
和y
的代码 - 例如,VLIW 体系结构。
为了解决这个问题,将它们分成两个不同的语句。
PS:不要忘记人类在执行算术运算时可能会犯错误。因此,最好通过在不同的语句中分隔操作来使操作更清晰。我希望我有所帮助。
int main()
{
int a = 3;
int b = 4;
/* Two different Statements*/
b = a;
/* or a = a + b - a */
a = a + b - b;
cout<<"a :"<<a<<" "<<"b :"<<b<<"n";
return 0;
}
a = b + a - a;
只是写成
a = b + a - (b = a)
------>> (经验 1)
以下三个结果与 (exp 1) 相同a = (b + a - (b = a));
a = ((b + a) - (b = a));
a = (b + a) - (b = a);
观察 +, - 运算符具有相同的优先级,并且具有从左到右的关联性 因此,首先执行"b+a",然后在减法之前将"a"值分配给"b">
现在观察以下内容 当 a = 10 且 b = 20 时;
a = (b = a) - b + a;
========> a = 10; b = 10a = ((b = a) - b + a);
========> a = 10;b = 10
a = ((b = a) - (b + a));
========> a = -10; b = 10 从上面的表达式中可以清楚地看出,即使最里面的括号首先被执行,也首先遵循结合性,然后是优先级。
注意: 避免混淆外括号和内括号的优先级 考虑以下表达式a = (b + a - (b = a))
=====> 实际结果 => a = 20, b = 10; 本来是 a = 10,b = 10;(如果与结合性相比,优先级是主要的) 因此,通过上面的例子,我们可以说,与优先级相比,结合性是主要的。
- 警告 C4552:">>":未使用表达式的结果
- #define Dbg(fmt,..) (0) 是什么意思? 警告:表达式无效
- MISRA 警告<复杂表达式隐式转换为不同的基本类型>
- C++ 斯特劳斯特鲁普的"std_lib_facilities.h"字符串结构 – 警告:无符号表达式的比较
- 如何消除"仅使用常量表达式索引到数组"警告?
- 为什么表达式 a = a + b - ( b = a ) 在 c++ 中给出序列点警告?
- 是“警告 C4127”(条件表达式是常量)曾经有帮助
- 发布模式下的正则表达式提升库链接在使用 mingw-w64 工具链时警告"duplicate section has different size"
- 警告:有符号和无符号整数表达式之间的比较
- 警告:表达式结果未使用
- 为什么这个C++表达式甚至不会生成警告?
- C++:警告:有符号和无符号表达式(Gmake,freebsd)
- 如何在使用static_assert时避免关于无返回表达式的警告
- 有符号和无符号整数表达式之间的比较在make install时发出警告
- 我的For循环出了什么问题?我得到警告:有符号和无符号整数表达式之间的比较[-Wsigncompare]
- 警告——与指针组合的算术表达式中存在可疑截断
- 警告:有符号和无符号整数表达式之间的比较.如何解决它
- 警告:有符号和无符号整数表达式之间的比较[-Wsign-compare]
- 警告C4127:cl命令中的条件表达式为常量
- C++正则表达式、未知转义序列'.'警告