# Why C compilers optimize switch and if differently

If you explicitely enumerate all the cases, gcc is very efficient :

```
int c(int num) {
num &= 0xF;
switch (num) {
case 0: case 1: case 8: case 9:
return -1;
case 4: case 5: case 12: case 13:
return 1;
case 2: case 3: case 6: case 7: case 10: case 11: case 14: case 15:
//default:
return 0;
}
}
```

is just compiled in a simple indexed branch :

```
c:
and edi, 15
jmp [QWORD PTR .L10[0+rdi*8]]
.L10:
.quad .L12
.quad .L12
.quad .L9
.quad .L9
.quad .L11
.quad .L11
.quad .L9
.quad .L9
.quad .L12
etc...
```

Note that if `default:`

is uncommented, gcc turns back to its nested branch version.

C compilers have special cases for `switch`

, because they expect programmers to understand the idiom of `switch`

and exploit it.

Code like:

```
if (num == 0 || num == 1 || num == 8 || num == 9)
return -1;
if (num == 4 || num == 5 || num == 12 || num == 13)
return 1;
```

would not pass review by competent C coders; three or four reviewers would simultaneously exclaim "this should be a `switch`

!"

It's not worth it for C compilers to analyze the structure of `if`

statements for conversion to a jump table. The conditions for that have to be just right, and the amount of variation that is possible in a bunch of `if`

statements is astronomical. The analysis is both complicated **and** likely to come up negative (as in: "no, we can't convert these `if`

s to a `switch`

").