Collin Biedenkapp
Collin Biedenkapp

Reputation: 511

C++ Conditional Operator versus if-else

I have always wondered about this. Let's say we have a variable, string weight, and an input variable, int mode, which can be 1 or 0.

Is there a clear benefit to using:

weight = (mode == 1) ? "mode:1" : "mode:0";

over

if(mode == 1)
    weight = "mode:1";
else
    weight = "mode:0";

beyond code readability? Are speeds at all affected, is this handled differently by the compiler (such as the ability of certain switch statements to be converted to jump tables)?

Upvotes: 3

Views: 2139

Answers (3)

Drew Hall
Drew Hall

Reputation: 29065

The key difference between the conditional operator and an if/else block is that the conditional operator is an expression, rather than a statement. Thus, there are few places you can use the conditional operator where you can't use an if/else. For example, initialization of constant objects, like so:

const double biasFactor = (x < 5) ? 2.5 : 6.432;

If you used if/else in this case, biasFactor would have to be non-const.

Additonally, constructor initializer lists call for expressions rather than statements as well:

X::X()
  : myData(x > 5 ? 0xCAFEBABE : OxDEADBEEF)
{
}

In this case, myData may not have any assignment operator or non-const member functions defined--its constructor may be the only way to pass any parameters to it.

Also, note that any expression can be turned into a statement by adding a semicolon at the end--the reverse is not true.

Upvotes: 3

J-Mik
J-Mik

Reputation: 896

With mingw, the assembly code generated with

const char *  testFunc()
{
    int mode=1;
    const char * weight = (mode == 1)? "mode:1" : "mode:0";
    return weight;
}

is:

testFunc():
0040138c:   push %ebp
0040138d:   mov %esp,%ebp
0040138f:   sub $0x10,%esp
10          int mode=1;
00401392:   movl $0x1,-0x4(%ebp)
11          const char * weight = (mode == 1)? "mode:1" : "mode:0";
00401399:   cmpl $0x1,-0x4(%ebp)
0040139d:   jne 0x4013a6 <testFunc()+26>
0040139f:   mov $0x403064,%eax
004013a4:   jmp 0x4013ab <testFunc()+31>
004013a6:   mov $0x40306b,%eax
004013ab:   mov %eax,-0x8(%ebp)
12          return weight;
004013ae:   mov -0x8(%ebp),%eax
13        }

And with

const char *  testFunc()
{
    const char * weight;
    int mode=1;
    if(mode == 1)
        weight = "mode:1";
    else
        weight = "mode:0";

    return weight;
}

is:

testFunc():
0040138c:   push %ebp
0040138d:   mov %esp,%ebp
0040138f:   sub $0x10,%esp
11          int mode=1;
00401392:   movl $0x1,-0x8(%ebp)
12          if(mode == 1)
00401399:   cmpl $0x1,-0x8(%ebp)
0040139d:   jne 0x4013a8 <testFunc()+28>
13              weight = "mode:1";
0040139f:   movl $0x403064,-0x4(%ebp)
004013a6:   jmp 0x4013af <testFunc()+35>
15              weight = "mode:0";
004013a8:   movl $0x40306b,-0x4(%ebp)
17          return weight;
004013af:   mov -0x4(%ebp),%eax
18        }

Pretty much the same code is generated. The performance of your application shouldn't depend on small details like this one.

So, no it doesn't make a difference.

Upvotes: 0

melpomene
melpomene

Reputation: 85897

No, this is purely about presenting the code to a human reader. I'd expect any compiler to generate identical code for these.

Upvotes: 0

Related Questions