LaoMao
LaoMao

Reputation: 179

Shocked by the strange behavior of unordered_map

It is a very simple piece of code:

#include <cstdio>
#include <unordered_map>

int main() {  
    std::unordered_map<int, int> m;
    m[1] = m.find(1) == m.end() ? 0 : 1;
    printf("%d\n", m[1]);
    return 0;
}

If the map does not contain 1, then assign m[1]=0; otherwise m[1]=1. I tried this with different gcc compilers here.

gcc5.2 always outputs 1, gcc7.1 always outputs 0.

Why is it so different? Shouldn't it be 0 always? I cannot understand this behavior. What is the safest way to write such logic?

Upvotes: 10

Views: 798

Answers (1)

Vlad from Moscow
Vlad from Moscow

Reputation: 310910

The result is dependent on whether the compiler supports C++ 2017 or not.

According to the C++ 2017 Standard (5.18 Assignment and compound assignment operators)

1 The assignment operator (=) and the compound assignment operators all group right-to-left. All require a modifiable lvalue as their left operand and return an lvalue referring to the left operand. The result in all cases is a bit-field if the left operand is a bit-field. In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression The right operand is sequenced before the left operand.. With respect to an indeterminately-sequenced function call, the operation of a compound assignment is a single evaluation

On the other hand according to the C++ 2014 Standard (5.18 Assignment and compound assignment operators)

1 The assignment operator (=) and the compound assignment operators all group right-to-left. All require a modifiable lvalue as their left operand and return an lvalue referring to the left operand. The result in all cases is a bit-field if the left operand is a bit-field. In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression. With respect to an indeterminately-sequenced function call, the operation of a compound assignment is a single evaluation.

As you can see the statement in bold is absent in the quote from the C++ 2014 Standard.

So you should not rely on the order of the evaluation of the left and the right operands.

Upvotes: 26

Related Questions