C++ ternary operators, Any difference?

Viewed 635

I was reading about the difference of the following:

1)

std::string test = level > 10 ? "Master" : "Beginner";

2)

std::string test;
if (level > 10)
    test = "Master";
else
    test = "Beginner";

And in the second case I was told that in the second option a temporary value is being create which I don't understand.

I learnt that when we declare a variable without initialisation it takes garbage, so the compiler just holds a memory location and doesn't "work" to change its value.

3 Answers

Syntactically, the first case is somewhat equivalent to this:

constexpr const char* f(int level) {
    if (level > 10)
        return "Master";
    else
        return "Beginner";
}

std::string test = f(level);

Here, test is immediately initialized with either "Master" or "Beginner". In the second case, test is first default-initialized, then either value is assigned to it.

However, this is not necessarily true after optimizations: the compiler can very well generate the exact same code in both cases.

when we declare a variable without initialisation it takes garbage

That is only true for fundamental and POD types, not classes like std::string which have a default-constructor. Look up default-initialization for details.

There're no temporary objects constructed in both cases.

In the 1st case, test is copy-initialized from the const char* returned by the ternary operator directly, via the constructor of std::string taking const char*.

In the 2nd case, test is default-initialized firstly, then assgined from the const char* in the if or else branch via the assignment operator of std::string. (BTW: After default-initialization test won't take garbage, it'll be initialized by the default constructor of std::string as empty string.)

There is no reason not to use the first form, but the compiler would have grievous performance issues if it didn't produce the same code for either. Having said that, the first form is clear and easy to understand, and might give the optimizer less work to do, so you might as well use it. It clearly states the intent to initialize the variable to one of two given values, and the code that expresses intent most clearly often produces the best generated code (as well as being easiest to understand.)

Related