> In fact, the compiler can see that simple call through the jump table and optimize it even better - maybe even by inlining.
Sure, if the table is `static const`. Otherwise the compiler generates code to load the table address, add the offset, retrieve the address and then jump to it.
If the table is defined in the current translation unit[1], or if it is visible but not const[2], or if it is visible but not static[3][4], the compiler cannot safely inline anything.
If the table is:
a) Defined in the current function
b) Does not escape the scope of the current function
c) Is qualified with static
d) Is qualified with const
Then sure, the compiler can figure out the best optimisation. Luckily, for benchmark purposes all of the above will be true so your benchmark program will show a performance benefit to the jump table.
Real programs with jump tables are never able to satisfy all those conditions.
[1] If defined elsewhere, the compiler doesn't know the contents of the table and so has generate code to look it up every time.
[2] If it isn't const, the compiler cannot assume that the entries in the table don't change, and thus has generate code to look it up every time.
[3] If the table is visible outside of the current scope or translation unit, the compiler cannot assume that the entries don't change, and once again has to generate code to perform the lookup every time.
[4] If the table is defined in the current function but not static, the compiler will have to generate code to populate that table every single time the function is entered.