>Нисколько не смущает, так как ничего не теряется. Естественно, этот
>подход возможен _не_везде_и_не_всегда_. Но, допустим, мы заранее знаем,
>сколько у нас вариантов выбора - тогда грех не использовать преимущества
>более скоростного подхода.
видимо, я как-то не так выразился.
при index &= mask; value = array[index]; ошибка выхода индекса за границы массива игнорируется. да, вы не получите SIGSEGV, ибо последующее обращение к массиву будет корректным. но вы не избавляетесь от ошибки выхода индекса за границу массива, вы ее просто отбрасываете.
в случае с if (index >= MAX_VALUE) уже вам решать что делать: игнорировать ошибку, обрабатывать ее или еще что-то.
> А если речь идет не про switch, а про
>обычный массив? Скомпилируй исходный код и сравни, что получится. Представь, что
>такая проверка идет в БОЛЬШОМ цикле.
>
>#define MAX_ARRAY 256
>
>int my_array[ MAX_ARRAY ];
>
>void test_func1( unsigned int index )
>{
>
> if( index < MAX_ARRAY )
> {
> // Делаем что-то очень полезное
> }
>
>}
>
>// Версия, оптимизированная под массив, размер которого 2 в какой-то
>// степени. К сожалению, этот фокус получается редко
>void test_func2( unsigned int index )
>{
> index = index & 0xFF;
> // Далее делаем что-то полезное
>}
>Сравните машинный код.
foo2_: cmp eax,00000100H
jae short L9
foo3_: and eax,000000ffH
это конечно же принципиальная разница с точки зрения производительности.. а вот с точки зрения логики работы программы - да, принципиальная.
>Рекомендую Вам также попробовать на практике то, про что я писал выше.
таблицу переходов ? каждый день использую как минимум неявным образом..
void
foo(int val)
{
switch (val) {
case 0 :
printf("Value 0\n");
break;
case 1 :
printf("Value 1\n");
break;
case 2 :
printf("Value 2\n");
break;
case 5 :
printf("Value 5\n");
break;
case 8 :
printf("Value 8\n");
break;
default :
printf("Invalid value\n");
break;
}
}
L1 DD L2
DD L3
DD L4
DD L7
DD L7
DD L5
DD L7
DD L7
DD L6
foo_: cmp eax,00000008H
ja short L7
jmp dword ptr cs:L1[eax*4]
L2: push offset DGROUP:L10
jmp short L8
L3: push offset DGROUP:L11
jmp short L8
L4: push offset DGROUP:L12
jmp short L8
L5: push offset DGROUP:L13
jmp short L8
L6: push offset DGROUP:L14
jmp short L8
L7: push offset DGROUP:L15
L8: call near ptr printf_
add esp,00000004H
ret
>Может быть тогда Вы лучше меня поймете.
идея таблицы переходов и так очевидна и прозрачна, я с этим совершенно не спорю :)
> Кстати, если я использую таблицу переходов, то по умолчанию инициализирую ее какой либо функцией-заглушкой,
>дабы не было мучительно больно из-за перехода хрен знает куда. Эта функция
>и есть аналог default в switch.
не совсем. default в switch обрабатывает все значения, не входящие в заданное множество. в то время как заглушка - лишь их подмножество.
// wbr