pour les déclarations dans les switches, mieux vaut leur mettre des blocs de portée propres {} ça evite que le compilo ne rale.
Sinon, le pointeur sur fonction dans ce cas peut sembler interessant... mais c´est une lourdeur et une contrainte supplementaire ( pointeurs de memes types) ; quant au break, il ne fait que générer un jmp supplémentaires pour ne effectuer les instructions suivantes.
Mais oui, tu peux gagner qq instructions en passant par des pointeurs et en fournissant une table de sauts statique, plutot que laisser le compilo tester les cas et brancher où il faut
La preuve par l´exemple :
int a;
int b = rand()%2;
switch ( b)
{
case 0:
a = 0;
break;
case 1:
a = 1;
case 2:
a = 2;
}
std::cout < < a;
le rand, c´est pour que le compilo n´optimise pas un jmp statique, le cout c´est pour que le code ne soit considéré comme " inactif" et générer effectivement des instructions.
En compilant en release, on obtient ceci :
; 23 : int a;
; 24 : int b = rand()%2;
call _rand
and eax, -2147483647 ; 80000001H
jns SHORT $LN71@main
dec eax
or eax, -2 ; fffffffeH
inc eax
$LN71@main:
; 25 : switch ( b)
sub eax, 0
je SHORT $LN15@main
sub eax, 1
je SHORT $LN14@main
sub eax, 1
jne SHORT $LN70@main
$LN14@main:
; 29 : break;
; 30 : case 1:
; 31 : a = 1;
; 32 : case 2:
; 33 : a = 2;
mov eax, 2
jmp SHORT $LN16@main
$LN15@main:
; 26 : {
; 27 : case 0:
; 28 : a = 0;
xor eax, eax
jmp SHORT $LN16@main
$LN70@main:
mov eax, DWORD PTR _a$[esp+4]
$LN16@main:
push ebx
push esi
push edi
; 34 : }
je vous passe le cout final qui n´est qu´un call.
Qu´est-ce qu´on voit ? des je et des jne pour brancher au bon cas. Donc oui, si tu as BCP de case dans ton switch, tu risques d´y perdre.
D´un autre coté, un déréférencement de pointeur risque de générer un far jump, qui coute aussi...
Perso, je recommande la conduite suivante : des switch avec peu de cas, et des petits bouts de code dans les cases : c´est un bon compromis souplesse/efficacité.
Ce point est d´ailleurs discuté dans un Gems d´ailleurs il me semble, mais je ne sais plus lequel :-?