На страницах Хабра не раз встречались статьи, которые прямо (или косвенно) озвучивали утверждение, что операторы языков программирования "case" и "switch" являются "синтаксическим сахаром" т.е. являются более удобной и наглядной записью последовательности операторов "if". В комментариях, с моей стороны, отмечалось недоумение, по поводу таких заявлений. Для справки приведу общий вид оператора "case" из языка программирования Турбо Паскаль.
case <ключ выбора> of
значение_1: операторы; ... значение_N: операторы;
else операторы;
end;
Когда я учился в университете основам Турбо Паскаля, наш преподаватель сознательно делал акцент на том, что данная синтаксическая конструкция, после вычисления ключа выбора, переходит на соответствующие вычисленному ключу операторы. То есть, без перебора всех ключей, сразу. В этом особенность данного оператора и его принципиальное отличие от последовательности операторов "if" (функционально эквивалентных). Так меня учили.
Авторы статей, считающие иначе, проявили завидное упорство (в комментариях), отстаиваю свою позицию, что привело к желанию разобраться в этом вопросе. (Однажды был даже такой удивительный случай, когда, вероятно начинающий программист, написал статью приблизительно следующего содержания: "А что если ключей выбора очень много? Перебор всех вариантов это долго. А что если попытаться оптимизировать такой нерациональный оператор как "case", "switch"." И далее рецепты по оптимизации. После справедливых замечаний в комментариях автор статью удалил. Ну что же, с кем не бывает.)
Приступил к штудированию литературы. Изначальна хотел развернуть данную тему более подробно, но поиски показали, что все авторы исповедуют принцип языков высокого уровня, т.е. программист работает с абстракцией и не его дело, каким образом принимается решение, на какую ветвь операторов перейти. То ли по щучьему велению, то ли гномик с искусственным интеллектом говорит: "Туда". Нас как пользователей не должно волновать, что происходит "под капотом". Тем не менее, считаю, что понимать это важно.
На уровне догадок и здравого смысла из "Систематическое программирование. Введение." Н.Вирт, можно предполагать, что данная синтаксическая конструкция языка программирования работает так, как меня учили. Об этом говорит приведённая в книге блок-схема (Да, да. Тогда ещё рисовали блок-схемы. Стр. 50).

В то же время в книге "Программирование и отладка в Delphi. Учебный курс." Митчелл К. Керман (Стр. 145) указано прямо противоположное.

Изучение материалов из литературы завело в тупик. Разбавим теоретические рассуждения парой примеров демонстрирующих какой код дают компиляторы GCC и FreePascal.
Любимый мною FreePascal неприятно удивил тем, что на любое количество вариантов выбора генерировал последовательное сравнение ключа выбора с вариантами. Заставить компилятор FreePascal поступать иначе можно исключительно передачей, в качестве параметра, ключа компиляции "-O3". И это ещё не всё. Дело в том, что пока число вариантов не превышает 12-ть, всё равно будет проверять все варианты последовательно. А вот когда вариантов больше 12-ти, тогда он начинает строить таблицу переходов, что бы после однократного вычисления ключа, перейти к требуемой ветви.
;фрагмент ассемблерного листинга. Последовательная проверка
; [10] CASE i OF
%LINE 10+0
mov ax,word [U_P_$$_I]
test ax,ax
jl ..@j4
test ax,ax
je ..@j5
sub ax,1
je ..@j6
sub ax,1
je ..@j7
sub ax,1
je ..@j8
sub ax,1
je ..@j9
sub ax,1
je ..@j10
sub ax,1
je ..@j11
sub ax,1
je ..@j12
sub ax,1
je ..@j13
sub ax,1
je ..@j14
sub ax,1
je ..@j15
sub ax,1
je ..@j16
jmp ..@j4
;фрагмент ассемблерного листинга. Таблица переходов
; [10] CASE i OF
%LINE 10+0
mov ax,dx
cmp ax,11
ja ..@j4
and eax,65535
mov rsi,qword ..@d1
movsxd rax,dword [rsi+rax*4]
add rax,rsi
jmp rax
А вот GCC ведёт себя более здраво (с моей точки зрения). Если число вариантов не превышает четырёх, то GCC генерирует последовательные проверки. Вполне разумно, какая разница одно сравнение или три. И зачем тогда "городить огород" с таблицей переходов. А вот при большем количестве вариантов, однозначно генерируется таблица переходов.
;фрагмент ассемблерного листинга. Последовательная проверка вариантов
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $2, -4(%rbp)
movl $1, -8(%rbp)
movl $5, -12(%rbp)
movl $8, -16(%rbp)
cmpl $2, -4(%rbp)
je .L2
cmpl $2, -4(%rbp)
jg .L3
cmpl $0, -4(%rbp)
je .L4
cmpl $1, -4(%rbp)
je .L5
jmp .L3
;фрагмент ассемблерного листинга. Таблица переходов.
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $2, -4(%rbp)
movl $1, -8(%rbp)
movl $5, -12(%rbp)
movl $8, -16(%rbp)
cmpl $4, -4(%rbp)
ja .L2
movl -4(%rbp), %eax
leaq 0(,%rax,4), %rdx
leaq .L4(%rip), %rax
movl (%rdx,%rax), %eax
cltq
leaq .L4(%rip), %rdx
addq %rdx, %rax
jmp *%rax
Вот так, однозначно доказать, что это не "синтаксический сахар", не получилось. Но и от своего твёрдого убеждения, что реализовывать данную синтаксическую конструкцию нельзя ни как иначе, нежели при помощи таблицы переходов, не отступаю! Всех с наступающим, надеюсь данное чтиво кому нибудь пригодится или будет интересно.
