Didn't I say that in the first place....?
Switches have to be constant...so you could just use a series of ifs
Didn't I say that in the first place....?
Switches have to be constant...so you could just use a series of ifs
Woop?
As I understand it, switch statement is kind of like an array of instructions. A jump table is created, which is like an array of pointers to the code for each case. I.e., for case 1, the code at address jump_table[1] is executed. case 2, the code at jump_table[2] is executed, and so on. That makes using the switch much faster than a long chain of if/else statements, for the same reason that it's quicker to go to the nth element in an array than it is in a linked list (although a good compiler might optimize away that long chain of if/else statements into something like a switch). I know I'm not answering your question, but I hope it clears switches up a bit.
Also, I think statements like 0 || 1, 1 || 2, 2 || 3, etc. evaluate (as integers) to 1 if either operand is non-zero, and zero in the case 0 || 0, since || is a boolean and not an integer operator.
I.e., 2 || 3 evaluates to int(bool(2) || bool(3))
which evals to int(true || true)
which evals ti int(true)
which evals to 1
Hmm... Strange. I always thought a switch was just an easier way of writing an if/else if chain, but according to the assembly output the if/else if chain is actually shorter:
Code:int main() { 00401800 push ebp 00401801 mov ebp,esp 00401803 sub esp,8 int i = 0; 00401806 mov dword ptr [i],0 cin >> i; 0040180D lea eax,[i] 00401810 push eax 00401811 mov ecx,dword ptr [__imp_std::cin (40203Ch)] 00401817 call dword ptr [__imp_std::basic_istream<char,std::char_traits<char> >::operator>> (402038h)] switch ( i ) 0040181D mov ecx,dword ptr [i] 00401820 mov dword ptr [ebp-8],ecx 00401823 cmp dword ptr [ebp-8],0 00401827 je main+37h (401837h) 00401829 cmp dword ptr [ebp-8],1 0040182D je main+40h (401840h) 0040182F cmp dword ptr [ebp-8],2 00401833 je main+49h (401849h) 00401835 jmp main+50h (401850h) { case 0: i = 10; 00401837 mov dword ptr [i],0Ah break; 0040183E jmp main+50h (401850h) case 1: i = 11; 00401840 mov dword ptr [i],0Bh break; 00401847 jmp main+50h (401850h) case 2: i = 12; 00401849 mov dword ptr [i],0Ch break; } return 0; 00401850 xor eax,eax }Code:int main() { 00401800 push ebp 00401801 mov ebp,esp 00401803 push ecx int i = 0; 00401804 mov dword ptr [i],0 cin >> i; 0040180B lea eax,[i] 0040180E push eax 0040180F mov ecx,dword ptr [__imp_std::cin (40203Ch)] 00401815 call dword ptr [__imp_std::basic_istream<char,std::char_traits<char> >::operator>> (402038h)] if ( i == 0 ) 0040181B cmp dword ptr [i],0 0040181F jne main+2Ah (40182Ah) i = 10; 00401821 mov dword ptr [i],0Ah 00401828 jmp main+46h (401846h) else if ( i == 1 ) 0040182A cmp dword ptr [i],1 0040182E jne main+39h (401839h) i = 11; 00401830 mov dword ptr [i],0Bh 00401837 jmp main+46h (401846h) else if ( i == 2 ) 00401839 cmp dword ptr [i],2 0040183D jne main+46h (401846h) i = 12; 0040183F mov dword ptr [i],0Ch return 0; 00401846 xor eax,eax }
Did you compile with no optimization? A switch statement shouldn't result in comparisons being done for every possible value (the list of cmp and je statements bunched together in the first example). It kind of defeats the purpose of having a switch statement in the language (an if/else chain is certainly more readable and less error prone, since it doesn't need the case labels or break statements).
Maybe the assembly for the switch program came out like that since there are so few cases (0,1,2, and default).
Last edited by 3rdcoast; 08-01-2008 at 10:44 PM.
I used VC++ 2008 express in Release mode. Maybe gcc could optimize better?
Although I don't see how a switch could possibly not check each case? It would have to be psychic then. I can try adding more cases to see if that makes a difference...
One more thing that has me confused is why VC++ used a sub instruction on the 3rd line after main() in the switch version and a push in the if/else version? I'm not that great with assembly, so I don't have a clue why it's different.
While someone provided an answer here is another possible one:
Code:switch(x) { case 0: cout<<"X is either 0 or 1"<<endl; break; case 1: cout<<"X is either 0 or 1"<<endl; cout<<"X is either 1 or 2"<<endl; break; case 2: cout<<"X is either 1 or 2"<<endl; cout<<"X is either 2 or 3"<<endl; break; case 3: cout<<"X is either 2 or 3"<<endl; break; }
My best guess is that the compiler determined the brute force way wasn't too bad with 4 cases. Either that, or MS wants you to buy the pro compiler to get the benefits of using jump tables in switches (wow, that would suck if VC Express is crippled that badly).
Briefly, here's what Patterson & Hennessey (not the Hennessey & Patterson book!) has to say:
Maybe Microsoft just hates C++ and is sabotaging it to force you to use C#. :lolOriginally Posted by Computer Organization and Design: The Hardware / Software Interface
No seriously, in Visual Studio 2005 (Pro!) you'll get deprecation warnings when using STL algorithms. I'll give you an example of of copying an array using STL:
This produces the following warning:Code:#include <algorithm> /* std::copy */ int main() { int A[] = {1,2,3,4,5,6,7,8,9,10}; int B[10]; std::copy(&A[0],&A[10],&B[0]); return 0; }
LMAO @ Microsoft telling me not to use the STL!Code:>------ Build started: Project: somecrap, Configuration: Debug Win32 ------ 1>Compiling... 1>main.cpp 1>f:\apps\visual-studio\vc\include\xutility(2282) : warning C4996: 'std::_Copy_opt' was 1> declared deprecated 1> f:\apps\visual-studio\vc\include\xutility(2270) : see declaration of 'std::_Copy_opt' 1> Message: 'You have used a std:: construct that is not safe. See documentation on how to use 1> the Safe Standard C++ Library' 1> f:\code\visual\somecrap\somecrap\main.cpp(121) : see reference to function template 1> instantiation '_OutIt std::copy<int*__w64 ,int*__w64 >(_InIt,_InIt,_OutIt)' being compiled 1> with 1> [ 1> _OutIt=int *__w64 , 1> _InIt=int *__w64 1> ] 1>Linking... 1>Embedding manifest... 1>Build log was saved at "file://f:\code\visual\somecrap\somcrap\Debug\BuildLog.htm" 1>somecrap - 0 error(s), 1 warning(s) ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
Last edited by 3rdcoast; 08-02-2008 at 12:10 AM.