在回答了这个问题之后,关于有问题的代码是否是未定义的行为进行了长时间的讨论。这是代码:
std::map<string, size_t> word_count;
word_count["a"] = word_count.count("a") == 0 ? 1 : 2;
首先,这是公认的,这至少是未指定的。结果根据首先评估作业的哪一侧而有所不同。在我的回答中,我跟踪了四个结果案例中的每一个,其中首先评估了哪一方的因素以及该元素在此之前是否存在。
还出现了一个简短的表格:
(x = 0) = (x == 0) ? 1 : 2; //started as
(x = 0) = (y == "a") ? 1 : 2; //changed to
我声称它更像这样:
(x = 0, x) = (x == 0) ? 1 : 2; //comma sequences x, like [] should
最终,我找到了一个似乎对我有用的例子:
i = (++i,i++,i); //well-defined per SO:Undefined Behaviour and Sequence Points
回到原来的,我把它分解成相关的函数调用,以便更容易理解:
operator=(word_count.operator[]("a"), word_count.count("a") == 0 ? 1 : 2);
^ inserts element^ ^reads same element
|
assigns to element
如果word_count["a"]
不存在,则有人认为它将被分配两次,而两者之间没有排序。如果我认为是真的两件事实际上是:
When a side is picked to be evaluated, the whole side has to be evaluated before the other side can start.
诸如 word_count["a"] = 1 之类的结构表现出明确定义的行为,即使在插入元素然后分配给它的情况下也是如此。
这两个说法是真的吗?最终,这实际上是未定义的行为吗?如果是,为什么第二个语句起作用(假设它起作用)?如果第二个是假的,我相信myMap[i]++;
世界上所有的 s 都是不正确的。
有用的链接:未定义的行为和序列点