-3

Have looked at this question: To ternary or not to ternary?, however it didn't really provide me with an answer to this situation.

I've been using ternary in if statements, as it, according to me, provides more logic and requires less operations to actually work. An example of such statement is: if (a == 'foo' ? b != 'poo' : true), which of course can be replaced by if ((a == 'foo' && b != 'poo') || a != 'foo'). If comparing the number of operations - between 1 and 2 for ternary and 2 and 3 for non (of course this is a trivial example - I can as well create an example where the difference is greater than 1), it's also a cleaner than the non-ternary (at least for me); however my co-workers have been asking why have I adopted such convention.

Are there any caveats of using ternaries within conditionals (apart for readability - I'm still considering a ? b ? c ? d : e : f : g inhumane thing to parse)?

Community
  • 1
  • 1
eithed
  • 3,933
  • 6
  • 40
  • 60

1 Answers1

1

Using ternaries in an if statement is a bad idea, if for no other reason than it's unexpected. It's also logically more difficult to follow - I mentally converted your ternary to a conditional, as it makes more sense thinking about it that way. If I think of the conditions, I'm going to think in terms of "and" and "or", not "if ... then ... else," and I think most devs will agree with me on that.

Finally, look at the disassembly. Using clang on OSX, they are identical except the ternary has one more jmp. Your "fewer operations" argument is wrong.

Ternary

_ternary:                               ## @ternary
    .cfi_startproc
## BB#0:
    pushq   %rbp
Ltmp2:
    .cfi_def_cfa_offset 16
Ltmp3:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp4:
    .cfi_def_cfa_register %rbp
    subq    $16, %rsp
    movl    %edi, -4(%rbp)
    movl    %esi, -8(%rbp)
    movl    %edx, -12(%rbp)
    cmpl    $102, -4(%rbp)
    jne LBB0_2
## BB#1:
    cmpl    $111, -8(%rbp)
    je  LBB0_3
    jmp LBB0_4
LBB0_2:
    cmpl    $111, -12(%rbp)
    jne LBB0_4
LBB0_3:
    leaq    L_.str(%rip), %rdi
    callq   _puts
    movl    %eax, -16(%rbp)         ## 4-byte Spill
LBB0_4:
    movl    $0, %eax
    addq    $16, %rsp
    popq    %rbp
    ret
    .cfi_endproc

Logical

_logical:                               ## @logical
    .cfi_startproc
## BB#0:
    pushq   %rbp
Ltmp7:
    .cfi_def_cfa_offset 16
Ltmp8:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp9:
    .cfi_def_cfa_register %rbp
    subq    $16, %rsp
    movl    %edi, -4(%rbp)
    movl    %esi, -8(%rbp)
    movl    %edx, -12(%rbp)
    cmpl    $102, -4(%rbp)
    jne LBB1_2
## BB#1:
    cmpl    $111, -8(%rbp)
    je  LBB1_3
LBB1_2:
    cmpl    $111, -12(%rbp)
    jne LBB1_4
LBB1_3:
    leaq    L_.str1(%rip), %rdi
    callq   _puts
    movl    %eax, -16(%rbp)         ## 4-byte Spill
LBB1_4:
    movl    $0, %eax
    addq    $16, %rsp
    popq    %rbp
    ret
    .cfi_endproc

Diff, excluding naming (< = ternary)

20,22c20,21
<   jmp LBB0_4
---
Kevin
  • 53,822
  • 15
  • 101
  • 132
  • Hm... I wonder why is that - are the ternary operations (after ?) evaluated irregardless of the condition (before ?). I can agree with the unexpected `if (if ())`, but wanted to know if there's anything worse lurking around in there. – eithed Apr 23 '14 at 15:50