Thread: Else If vs Switch statement

  1. #1
    Registered User
    Join Date
    Apr 2016
    Posts
    2

    Else If vs Switch statement

    I'm currently doing a Computer Science course and my professor is telling us to use Else if statements instead of Switch statements. I've done some searching and have used both and I find Switch statements are much more manageable in comparison.
    Can the same goal be achieved between the two?
    What are your thoughts on this?

    I wanted to use switch statement for a particular problem and he explicitly said to use Else If, and to use that for all future problems. I just find this odd...

  2. #2
    Registered User PenCzar's Avatar
    Join Date
    Apr 2016
    Location
    New York
    Posts
    7
    Nested if-statements can be quite messy, so I try to avoid abusing them. Using switch for every single control flow instance sounds a bit overkill, I use them mainly for menus. Both have their use depending on the situation.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    A switch statement can always be rewritten as a series of if / else if statements.

    Some other points.
    1. the cases in switch/case must be integral constants (though some compilers like gcc also support ranges). If/else if can evaluate expressions of any type.

    2. In switch/case, the select expression is evaluated only once. Every if/else if in the chain is evaluated until one of them is found to be true.

    3. The compiler is free to turn switch/case into if/else if, should the result be better code generation. An example being case 1: case 1000: case 1000000: would potentially result in very large jump tables.

    4. The need to use 'break' at the end of each case is simultaneously a good feature and a bad feature.


    Perhaps your professor should explain his reasoning, rather than issuing edicts.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Mar 2011
    Posts
    596
    Quote Originally Posted by Salem View Post
    ...
    3. The compiler is free to turn switch/case into if/else if, should the result be better code generation. An example being case 1: case 1000: case 1000000: would potentially result in very large jump tables.
    ...
    Would any compiler actually use the case values in the jump address values?

    Isn't that what the jump table is for - to map case values to jump addresses?

    -

  5. #5
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    Would any compiler actually use the case values in the jump address values?
    Isn't that what the jump table is for - to map case values to jump addresses?
    Code:
    // Program 1:
    
    #include <stdio.h>
    
    int main() {
        int n;
        printf(">>> ");
        scanf("%d", &n);
        switch (n) {
        case 0: puts("zero");  break;
        case 1: puts("one");   break;
        case 2: puts("two");   break;
        case 3: puts("three"); break;
        case 4: puts("four");  break;
        case 5: puts("five");  break;
        case 6: puts("six");   break;
        case 7: puts("seven"); break;
        case 8: puts("eight"); break;
        case 9: puts("nine");  break;
        }
        return 0;
    }
    
    Parial assembly listing:
    
        call    __isoc99_scanf
        movl    -4(%rbp), %eax
        cmpl    $9, %eax
        ja    .L2
        movl    %eax, %eax
        movq    .L4(,%rax,8), %rax
        jmp    *%rax
        .section    .rodata
        .align 8
        .align 4
    .L4:
        .quad    .L3
        .quad    .L5
        .quad    .L6
        .quad    .L7
        .quad    .L8
        .quad    .L9
        .quad    .L10
        .quad    .L11
        .quad    .L12
        .quad    .L13
        .text
    .L3:
        movl    $.LC2, %edi
        call    puts
        jmp    .L2
    .L5:
        movl    $.LC3, %edi
        call    puts
        jmp    .L2
    .L6:
        movl    $.LC4, %edi
        call    puts
        jmp    .L2
    etc.
    
    
    
    // Program 2
    
    #include <stdio.h>
    
    int main() {
        int n;
        printf(">>> ");
        scanf("%d", &n);
        switch (n) {
        case 0:         puts("zero");  break;
        case 10:        puts("one");   break;
        case 200:       puts("two");   break;
        case 3000:      puts("three"); break;
        case 40000:     puts("four");  break;
        case 500000:    puts("five");  break;
        case 6000000:   puts("six");   break;
        case 70000000:  puts("seven"); break;
        case 800000000: puts("eight"); break;
        case 900000000: puts("nine");  break;
        }
        return 0;
    }
    
    Partial assembly listing:
    
        call    __isoc99_scanf
        movl    12(%rsp), %eax
        cmpl    $40000, %eax
        je    .L3
        cmpl    $40000, %eax
        jg    .L4
        cmpl    $10, %eax
        je    .L5
        cmpl    $10, %eax
        jg    .L6
        testl    %eax, %eax
        .p2align 4,,3
        je    .L7
        .p2align 4,,6
        jmp    .L2
    .L6:
        cmpl    $200, %eax
        .p2align 4,,4
        je    .L8
        cmpl    $3000, %eax
        je    .L9
        jmp    .L2
    .L4:
        cmpl    $70000000, %eax
        je    .L10
        cmpl    $70000000, %eax
        jg    .L11
        cmpl    $500000, %eax
        je    .L12
        cmpl    $6000000, %eax
        je    .L13
        jmp    .L2
    .L11:
        cmpl    $800000000, %eax
        je    .L14
        cmpl    $900000000, %eax
        je    .L15
        jmp    .L2
    .L7:
        movl    $.LC2, %edi
        call    puts
        .p2align 4,,3
        jmp    .L2
    .L5:
        movl    $.LC3, %edi
        call    puts
        .p2align 4,,3
        jmp    .L2
    .L8:
        movl    $.LC4, %edi
        call    puts
        .p2align 4,,3
        jmp    .L2
    etc.

  6. #6
    Registered User
    Join Date
    Mar 2011
    Posts
    596
    Thanks for the example disassemblies.

    So it's not the magnitude of the case values that creates a larger jump table, but the arbitrary nature of the values that creates longer, more complex code?

    Small case values like case: 12, case: -2, case 3:, case: 14, would still result in assembly like program 2?

    -

  7. #7
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    Quote Originally Posted by megafiddle View Post
    So it's not the magnitude of the case values that creates a larger jump table, but the arbitrary nature of the values that creates longer, more complex code?

    Small case values like case: 12, case: -2, case 3:, case: 14, would still result in assembly like program 2?
    It's a little more complicated than that.

    Contiguous values from 1000000 to 1000010 work the same as program 1 simply by subtracting 1000000 from the values.

    Non-contiguous values that are relatively close to each other, like your example, can be handled with a jump table with dummy entries; example below.

    There seems to need to be at least X cases (not sure what X is, but let's say 10) for it to bother with the table approach.

    This is all with gcc, by the way, and the -S flag dumps the assembly.

    Below, all the .L2 labels are dummy entries in the table, jumping to the return statement.
    Code:
    // Program 3
    
    #include <stdio.h>
    
    int main() {
        int n;
        printf(">>> ");
        scanf("%d", &n);
        switch (n) {
        case 12: puts("alpha");   break;
        case -2: puts("beta");    break;
        case  3: puts("gamma");   break;
        case 14: puts("delta");   break;
        case -7: puts("epsilon"); break;
        case 22: puts("zeta");    break;
        case 18: puts("eta");     break;
        case 10: puts("theta");   break;
        case  0: puts("iota");    break;
        case  6: puts("kappa");   break;
        }
        return 0;
    }
    
    Partial assembly listing:
    
        call    __isoc99_scanf
        movl    -4(%rbp), %eax
        addl    $7, %eax
        cmpl    $29, %eax
        ja    .L2
        movl    %eax, %eax
        movq    .L4(,%rax,8), %rax
        jmp    *%rax
        .section    .rodata
        .align 8
        .align 4
    .L4:
        .quad    .L3
        .quad    .L2
        .quad    .L2
        .quad    .L2
        .quad    .L2
        .quad    .L5
        .quad    .L2
        .quad    .L6
        .quad    .L2
        .quad    .L2
        .quad    .L7
        .quad    .L2
        .quad    .L2
        .quad    .L8
        .quad    .L2
        .quad    .L2
        .quad    .L2
        .quad    .L9
        .quad    .L2
        .quad    .L10
        .quad    .L2
        .quad    .L11
        .quad    .L2
        .quad    .L2
        .quad    .L2
        .quad    .L12
        .quad    .L2
        .quad    .L2
        .quad    .L2
        .quad    .L13
        .text
    .L10:
        movl    $.LC2, %edi
        call    puts
        jmp    .L2
    .L5:
        movl    $.LC3, %edi
        call    puts
        jmp    .L2
    etc.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Different compilers (and even the same compiler with different compilation options) have a varying heuristic as to whether to go for the branching code or the jump table approach.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Mar 2011
    Posts
    596
    Now I got it.

    Thanks!

    -

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. 'If' Statement inside the Switch statement being ignored.
    By howardbc14 in forum C Programming
    Replies: 4
    Last Post: 04-11-2015, 11:45 AM
  2. Switch Statement Help
    By ShiroAzure in forum C++ Programming
    Replies: 2
    Last Post: 09-08-2011, 08:40 PM
  3. Switch Statement Help
    By IMMORTALX in forum C Programming
    Replies: 8
    Last Post: 09-06-2011, 08:24 PM
  4. Switch statement help
    By GeorgeV in forum C++ Programming
    Replies: 6
    Last Post: 08-07-2007, 03:35 AM
  5. After the switch statement?
    By cerin in forum C++ Programming
    Replies: 8
    Last Post: 03-02-2005, 08:01 PM