提问人:Maestro 提问时间:8/1/2022 最后编辑:Maestro 更新时间:8/2/2022 访问量:137
赋值运算符是 C++17 下的序列点吗?这种表达的结果会是什么?
Is assignment operator a sequence point under C++17? and what would be the result of this expression?
问:
建议不要在单个表达式中多次修改对象,也不要在同一表达式中修改对象后再使用它。
int i = 0;
++++i; // UB
++i = i++; // OK?
- 我认为最后一个表达式是 C++17 标准之前的 UB,但现在我想没关系,因为赋值运算符已成为序列点。
那么你怎么看?你能向我解释最后一个表达式中的值应该是什么吗?i
++i = i++;
我知道这样做的设计很糟糕,但这只是为了教育目的。谢谢。
当我针对 C++17 或 C++20 进行编译时:我仍然收到相同的警告:
g++ main.cpp -std=c++17 -o prog -Wall -pedantic
++i = i++;
这是 GCC 的输出:
main.cpp: In function ‘int main()’: main.cpp:12:12: warning: operation on ‘i’ may be undefined [-Wsequence-point] 12 | ++i = i++; | ~^~
.
答:
3赞
lorro
8/1/2022
#1
现在没有序列点:我们有序列之前和之后序列。当您有呼叫(或任何其他呼叫 - 内置或用户定义的呼叫)时,右侧在左侧之前排序。所以在 C++ 17 中有效,在 sequenced-before 中。operator=
operator@=
operator=
++i = i++
i++
++i
在 C++17 之前,正如你所写的,它是 UB。
评论
0赞
lorro
8/1/2022
@user17732522 已添加,谢谢。至于 C++ 之前的 17,它也在问题中(OP 认为它是 UB),但明确这一点是有道理的。
0赞
user17732522
8/1/2022
我可能太迂腐了,但作为另一个澄清,内置赋值运算符不是 s,也不涉及函数调用。(其他运营商也一样。operator=
0赞
bolov
8/1/2022
您可能想添加定义明确并且一直如此。++++i
1赞
user17732522
8/2/2022
@Maestro GCC 的开发人员决定保留警告,尽管该行为现在已经明确定义。我认为他们的理由是不应该编写这样的代码,并且不鼓励编写在更改标志时会损坏的代码。有一个错误报告。让我看看我能不能再找到它......-std
1赞
user17732522
8/2/2022
@Maestro 它实际上是这样记录的,见 gcc.gnu.org/onlinedocs/gcc/Warning-Options.html。-Wsequence-point
评论
++++i;