Ternary Operator in C

From EggeWiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

In writing C, I've often liked the ternary operator. It allows expressions to be computed in line, and shortens the amount of code one has to write. I've also believed that any ternary expression could be turned into a formula without any branching instructions. This can be important in a tight loop, as deeper pipelining can occur. In other languages which don't support the ternary operator, I've often used boolean expressions to achieve the same result. The following two expressions should be equivalent:

<geshi lang="c"> i = expr ? value1 : value2; // or i = expr * value1 + (!expr) * value2; </geshi>

This works for languages in which boolean expressions evaluate to 0 or 1. There in C is reasons that any ternary operator could be turned into a function.

Consider the following program:

<geshi lang="c"> int main(int argc, char *argv[]) {

 return argc == 1 ? 2 : 3;

} </geshi>

Using gcc 3.4.4, I compiled the above program. Here's the assembly it generated.

<geshi lang="asm">

       cmpl    $1, 8(%ebp)
       jne     L2
       movl    $2, -4(%ebp)
       jmp     L3

L2:

       movl    $3, -4(%ebp)

L3:

       movl    -4(%ebp), %eax
       leave
       ret

</geshi>

Recompiling the program with -O3 generates the following: <geshi lang="asm">

       xorl    %eax, %eax
       cmpl    $1, 8(%ebp)
       leave
       setne   %al
       addl    $2, %eax
       ret

</geshi>

So, in the first case, it does use branching instructions, but in the second case it inlines the result.

What would happen if we wrote the same code procedurally?

<geshi lang="c"> int main(int argc, char *argv[]) {

 if (argc == 1) {
   return 2;
 } else {
   return 3;
 }

} </geshi>

Without optimization, we create the same assembly as before: <geshi lang="asm">

       cmpl    $1, 8(%ebp)
       jne     L2
       movl    $2, -4(%ebp)
       jmp     L1

L2:

       movl    $3, -4(%ebp)

L1:

       movl    -4(%ebp), %eax
       leave
       ret

</geshi>

Turning the optimization on results in the same optimization which was made when we had the ternary operator. <geshi lang="asm">

       cmpl    $1, 8(%ebp)
       leave
       setne   %al
       addl    $2, %eax
       ret

</geshi>

In conclusion then, the ternary operator offers no performance benefit over using a control structure, and is simply a matter of style and preference.