将地图大小作为值插入到地图未定义行为中吗?

Is inserting map size as value into a map undefined behavior?

编辑:这个问题应该没有关闭,如果你看一下答案你会发现它们是完全不同的(旧问题没有提到C++17) .

我正在阅读 PVS blog post,其中提到了以下错误。

(减少)

std::map<int,int> m;
m[7]=5;
auto val = 15;
if (!m.contains(val)){
    m[val] = m.size(); // bug here
}

根据博客 post,这是错误的。 我一直认为 operator [] 对 map 的调用是一个函数调用,所以 .size() 在 [] 之前排序,因为函数充当序列点。

那么为什么这是一个错误?

注意:我知道自 C++11 以来不存在序列点,但我使用它们是因为新的措辞对我来说更难理解。

C++17 之前

§ 1.9 Program execution [intro.execution] (n3690 c++14 draft)

  1. Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.

和 5.17 [expr.ass] 没有提到内置赋值操作数之间的任何顺序。因此,内置赋值运算符 = 的两个操作数的求值相互之间是无序的。

m[val]m.size() 可以按任何顺序计算(甚至可以重叠 - 交错 CPU 指令)。

正在考虑:

  • m[val] 具有修改地图大小(标量)的副作用

  • m.size()的值计算访问地图的大小

§ 1.9 Program execution [intro.execution] (n3690 c++14 draft)

  1. [...] If a side effect on a scalar object is unsequenced relative to either [...] or a value computation using the value of the same scalar object, the behavior is undefined.

所以是的,行为确实是未定义的。

C++17

§8.5.18 Assignment and compound assignment operators [expr.ass] (n4713 C++17 draft)

  1. The assignment operator (=) [...] The right operand is sequenced before the left operand.

因此行为已定义。 m.size() 将在 m[val]

之前计算