【发布时间】:2020-05-01 16:18:54
【问题描述】:
编辑:此问题不应该被关闭,如果您查看答案,您会发现它们完全不同(旧问题未提及 C++17)。
我正在阅读一篇 PVS blog 帖子,其中提到了以下错误。
(减少)
std::map<int,int> m;
m[7]=5;
auto val = 15;
if (!m.contains(val)){
m[val] = m.size(); // bug here
}
根据博客文章,这是错误的。 我一直认为 map 的 operator [] 调用是一个函数调用,因此 .size() 在 [] 之前排序,因为函数充当序列点。
那么为什么这是一个错误?
注意:我知道自 C++11 以来不存在序列点,但我使用它们是因为新的措辞对我来说更难理解。
【问题讨论】:
-
在@cigien 提供的链接中this particular answer 对序列点进行了梳理。
-
这在我看来是 PVS 博文中的一个错误。排序可能未指定,但这与 UB 不同。
-
“我一直认为map的operator []调用是一个函数调用,所以.size()在[]之前排序,因为函数充当序列点” ints的赋值虽然没有
-
这种行为最近发生了变化。在 C++17 之前,这是未指定的行为。在 C++17 中,保证左侧在右侧之前排序,使其定义行为。我对可能的欺骗目标发表了评论,要求更新已接受的答案,以便对您来说是完整的。
-
@s3cur3 如果
m[val]和m.size()的序列不确定,那么你是对的。但它们是未排序的,它是 UB
标签: c++ sequence-points unspecified-behavior