Gaith
Gaith

Reputation: 828

Unexpected behavior from ternary operator

When I run this code:

#include <iostream>
#include <map>

using namespace std;

void f1() {
    map<int, int> m;
    m[5] = m.find(5) == m.end() ? 1 : 2;
    cout << m[5] << endl;
}
void f2() {
    map<int, int> m;
    if (m.find(5) == m.end())
        m[5] = 1;
    else
        m[5] = 2;
    cout << m[5] << endl;
}
int main() {
    f1();
    f2();
    return 0;
}

I get the following output:

2
1

Why am I getting wrong output when I am using ternary operator?

Upvotes: 0

Views: 123

Answers (2)

Ben Voigt
Ben Voigt

Reputation: 283614

The order of function calls is indeterminate and affecting your results. Consider:

void f1()
{
    map<int, int> m;
    int& result = m[5]; // creates m[5]
    auto it = m.find(5); // finds the empty m[5] created above
    int value = (it == m.end())? 1: 2;
    result = value;
    std::cout << m[5] << std::endl;
}

This is a perfectly legal implementation of the code you wrote.

There's nothing wrong with the ternary operator. This would work just fine:

bool notfound = (m.find(5) == m.end());
m[5] = notfound? 1: 2;

The important thing is whether m[5] could possibly be evaluated before m.find(5).

Upvotes: 2

Vlad from Moscow
Vlad from Moscow

Reputation: 310930

In this statement

m[5] = m.find(5) == m.end() ? 1 : 2;

you created object m[5] by placing it in the left side of the assignment. So m.find(5) != m.end() because m[5] already exists.

In fact there is the undefined behaviour because the order of evaluation of the left and the right operands of the assignment is not specified.

Upvotes: -1

Related Questions