Modern C compilers have the smarts built in to make intelligent decisions on what code to emit. In the case of your example of 2 widely spaced cases, it produces this
?live1@0:
;
; int main( int argc, char * argv[] ) {
;
push ebp
mov ebp,esp
push ecx
;
; unsigned long selector;
; sscanf( argv[1], "%li", &selector );
;
@1:
lea eax,dword ptr [ebp-4]
push eax
push offset s@
mov edx,dword ptr [ebp+12]
push dword ptr [edx+4]
call _sscanf
add esp,12
;
;
; switch ( selector ) {
;
mov ecx,dword ptr [ebp-4]
sub ecx,-2147483648
je short @5
sub ecx,-2147483647
jne short @2
;
; case 1 : printf( "case 1\n" );
+break;
;
push offset s@+4
call _printf
pop ecx
@8:
pop ecx
pop ebp
ret
;
; case 2147483648 : printf( "case 2147483648\n" );
+ break;
;
@5:
push offset s@+12
call _printf
pop ecx
@9:
pop ecx
pop ebp
ret
;
; default : printf( "default\n" );
+ break;
;
@2:
push offset s@+29
call _printf
pop ecx
;
; }
; }
;
@6:
@7:
pop ecx
pop ebp
ret
_main endp
_TEXT ends
Which as you can see, gets translated into a test and jump for the extreme case, another test and jump for the default case and a fall through for the 1 case.
If you combine a contiguous range and an extreme case, you get.
_TEXT segment dword public use32 'CODE'
_main proc near
?live1@0:
;
; int main( int argc, char * argv[] ) {
;
push ebp
mov ebp,esp
push ecx
;
; unsigned long selector;
; sscanf( argv[1], "%li", &selector );
;
@1:
lea eax,dword ptr [ebp-4]
push eax
push offset s@
mov edx,dword ptr [ebp+12]
push dword ptr [edx+4]
call _sscanf
add esp,12
;
;
; switch ( selector ) {
;
mov ecx,dword ptr [ebp-4]
cmp ecx,3
jg short @11
je short @7
sub ecx,-2147483648
je short @10
sub ecx,-2147483647
je short @9
dec ecx
je short @8
jmp short @2
@11:
sub ecx,4
je short @6
dec ecx
je short @5
dec ecx
je short @4
jmp short @2
;
; case 1 : printf( "case 1\n" );
+break;
;
@9:
push offset s@+4
call _printf
pop ecx
@14:
pop ecx
pop ebp
ret
;
; case 2 : printf( "case 2\n" );
+ break;
;
@8:
push offset s@+12
call _printf
pop ecx
@15:
pop ecx
pop ebp
ret
;
; case 3 : printf( "case 3\n" );
+ break;
;
@7:
push offset s@+20
call _printf
pop ecx
@16:
pop ecx
pop ebp
ret
;
; case 4 : printf( "case 4\n" );
+ break;
;
@6:
push offset s@+28
call _printf
pop ecx
@17:
pop ecx
pop ebp
ret
;
; case 5 : printf( "case 5\n" );
+ break;
;
@5:
push offset s@+36
call _printf
pop ecx
@18:
pop ecx
pop ebp
ret
;
; case 6 : printf( "case 6\n" );
+ break;
;
@4:
push offset s@+44
call _printf
pop ecx
@19:
pop ecx
pop ebp
ret
;
; case 2147483648 : printf( "case 2147483648\n" );
+ break;
;
@10:
push offset s@+52
call _printf
pop ecx
@20:
pop ecx
pop ebp
ret
;
; default : printf( "default\n" );
+ break;
;
@2:
push offset s@+69
call _printf
pop ecx
;
; }
; }
;
@12:
@13:
pop ecx
pop ebp
ret
_main endp
_TEXT ends
Which has been converted into a test cascade something like the original Perl code. However, this is before the optimiser has gone to work on it. Once the optimiser sees that code, it is quite likely that it will revert to using a dispatch table for the continuous cases with a single test for the extreme case. I having having trouble obtaining a post - optimisation disassembly that is readable. I'll try to update with that later.
As you might guess, if your range of cases is a widely spread set of discontiguous cases, then the result is you end up with cascaded tests just like the perl version. However, in almost every case (sic:) I remember using, I found some fairly simple function theat mapped the range to a contiguous or near-contiguous integer range. When this isn't the case, then I use an if/else cascade instead.
Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
Hooray!
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.
|
|