Just curious, is there any difference at all, or are both represented the same when put into asm?
Printable View
Just curious, is there any difference at all, or are both represented the same when put into asm?
Why not compile and see for yourself? It'll be compiler dependant, even down to the optimisation settings you use.
There's another thread going this way on the C forum.
I don't think I've ever seen for(;;) in a real program... only in books. Not that I've studied that many real programs!
To me, while(true) just looks better!
I personally only use while(true), but I wanted to know in case of an argument with my teacher or something. Knowledge is power :D
Hammer, when you say compile and see for myself, do you mean run it in a profiler or do you mean find some way to look at the assembly myself? And I'll check out that thread you're talking about :cool:
I've seen this used with looping thru a menu for example
sort of like :
That way the break statements gets you out of the infinite loop &Code:for (; ; ) ...
{
int choice = menu( );
switch(choice)
{
case ( 1 ):
some function( );
break;
case ( 2 ):
some other function();
break;
etc.
etc.
etc.
you can go thru as many case statements as you want....
If you had quite a few choices "while (true)" would lead to a lengthy "If statement"
the infinite for(; ; ) loop lets you use a switch statement instead..
Using something like MSVC you can look at the ASM while debugging. There are many compiler products that offer this feature.Quote:
Hammer, when you say compile and see for myself, do you mean run it in a profiler or do you mean find some way to look at the assembly myself? And I'll check out that thread you're talking about
What? You mean you can't put a switch statement inside a while loop? I'm not so sure about that, but I'll test it out... And also are you sure break will break out of both? I thought it would only break out of the switch, and if it DID break out of both, I would think that it would act in the same way with the while :confused:Quote:
the infinite for(; ; ) loop lets you use a switch statement instead..
Ok, thanks. But if I try compiling on Release settings, I won't have the debugger anymore. Is there some easy way to get the assembly from non-debug-mode executables, or will I need to get a decompiler of some sort?Quote:
Using something like MSVC you can look at the ASM while debugging. There are many compiler products that offer this feature.
Ummm... there are some apps that will convert the binary to ASM, since the conversion is rather easy. I don't know the names of any... some sort of hex editor/"disassembler" though
You know what, so does a while loop.Quote:
the infinite for(; ; ) loop lets you use a switch statement instead..
Hopefully your compiler would optimize the two to the same thing.
While(1) because im lazy and dont want to type true. When i read it outloud i always say "Loop Forever". I dont think there should be any major difference between while(1) and for(;;). true is just an enumeration of 1 isnt it? A literal 1? or am i mistaken...
Ok, I was hoping it would be that. But just in case, you know... like, if doing the while might require a check of some sort while the for would just loop without checking anything, maybe the for would be marginally more efficient or something. I'm about to grab a disassembler from somewhere though, I guess I'll have to see if there's any difference myself (even though I won't have a clue what's going on in the assembly :D)Quote:
Hopefully your compiler would optimize the two to the same thing.
Well yes you could you a switch statement in a while loop, but somebody said they had never seen a for(; ; ) loop used in a real program and someone wanted to see it used so they could discuss it with their teacher.....Actually with either it depends on how you code it.......Here is the full code with the snippet I posted earlier....A fellow over at source-forge wrote this for me..
The purpose of the example was to put as many examples of C++ code in one short snippet..... and I think he gave me 5 stars worth...........classes, reference, for(; ; ), whatever..it's in here...great learning example.........
Heh !Code:
// First, notice that the main() calls the function 'OperationWindow( )'
// that calls the 'menu()' and used in the switch within the 'OperationWindow( )'
// function.
// Note when 'n' is the choice for quit ?... the switch "re-calls" the
// function 'OperationWindow( )' to start a new.
// Also in main(), a pointer to mainClass 'mainClass *openNewMain = new mainClass ;'
// and the using 'new' sets aside the space in memory.
// Last after the program ends, the 'delete openNewMain ; openNewMain = 0 ;'
// frees the memory... and then sets 'openNewMain = 0 ' so not to leave trash
// in memory.
// Notice that no 'system("PAUSE")' has been added to the end of main().
// ********************************************************************
// This may not be world class programming, but I put a number of basic
// things to give an idea or two maybe.
#include<iostream>
class mainClass
{
public:
mainClass( ){}
~mainClass( ){}
int OperationWindow( );
void saldot ( );
void goback ( );
void endcall ( );
protected:
int menu( );
};
int mainClass::OperationWindow( )
{
bool nul_operation = false;
for (;;)
{
int choice = menu( );
switch(choice)
{
case ( 1 ):
saldot( );
break;
case ( 4 ):
nul_operation = true;
std::cout << "Quit Y-OR-N ? ";
char con; std::cin >> con;
if(con == 'y' || con == 'Y'){}
else OperationWindow( );
break;
default:
goback( );
break;
}
if ( nul_operation )
break;
}
}
int mainClass::menu( )
{
int choice;
std::cout << "\n mainClass Demo\n";
std::cout << "(Enter (1)> The only Choice !.\n";
std::cout << "(Enter (4)> Quit.\n\n";
std::cout << "|Here> ";
std::cin >> choice;
return choice;
OperationWindow( );
}
void mainClass::saldot( )
{
system("CLS");
std::cout <<"\n What ? ... Press Any Key to continue"<<"\n";
system("PAUSE > NUL");
}
void mainClass::goback( )
{
system("CLS");
std::cout <<"\nNot a selection... try again ... Press Any Key to continue"<<"\n";
system("PAUSE > NUL");
}
void mainClass::endcall( )
{
system("CLS");
std::cout <<"\n!!! A Request to close this program has been made ... close ?"<<"\n";
system("PAUSE > NUL");
}
int main( )
{
mainClass *openNewMain = new mainClass ;
openNewMain->OperationWindow( );
delete openNewMain ; openNewMain = 0 ;
return 0;
}
//j@ck_
This all started over How to make a counsel app stay up without using system("pause") or getch() or cin.get() etc.
Mm, well, I wasn't asking to see an example of for(;; ) in code, I was asking if there was any difference between it and while(1) (;)) when compiled (with full optimizations I meant, although I didn't say so). Anyways, I don't see where the "reference" is in that code, or for that matter, why a pointer to a mainClass is used instead of a simple object of it. And besides, I don't agree with this:
It's only setting a pointer which will never be used again anyways to NULL, the delete line is what got rid of the trash in memory. I appreciate your good intent though :)Quote:
and then sets 'openNewMain = 0 ' so not to leave trash in memory.
**EDIT**
Ok, I give up with the disassemblers. Both of the 2 that I tried had problems; the first was missing some debugging DLL, and the second was a trial version and said something about the test-file not being a valid hex file or something... I thought a hex file is just a normal text/binary/whatever file that you've opened in a hex editor or something?? :confused:
You should set it to NULL not 0. The only thing that this actually does is prevents you from accidently dereferencing a pointer that isn't pointing anywhere. The compiler should pick up the error.Quote:
and then sets 'openNewMain = 0 ' so not to leave trash in memory.
It is also worth reading this link.
Why don't you just write a short program with a for and a while loop and debug it. DevC++ let's you see the assembly code, M$VC++ probably too.
edit:
ok, I've compiled
andCode:for (;;) {
Sleep(0);
}
and both compiled to the exact same assembly code:Code:while (true) {
Sleep(0);
}
I just "copied" the loop because the CPU-window didn't allow copy/paste for some reason. Can anyone explain what 0x4012ce and 0x4012d8 are supposed to do ??Code:0x4012ce <main+30>: sub $0xc, %esp
0x4012d1 <main+33>: push $0x0
0x4012d3 <main+35>: call 0x415370 <Sleep@4>
0x4012d8 <main+40>: add $0xc, %esp
0x4012db <main+43>: jmp 0x4012ce <main+30>
another edit:
If a local function is used instead, the assembler code is just a call and a jmp so I figure it was just some kind of overhead for external calls. btw, goto compiles to the same code ;)
I'm no ASM expert.. in fact the only thing I know is how to spell it..
BUT - it looks like it is moving the pointer to the stack by 12 BYTES (??), pushing the number 0 onto the stack (the argument to sleep() ). Then it calls the sleep function then restores the pointer to the stack, then returns to the begining of the loop. Not sure exactly why it subtracts 12 from the extended stack pointer though.
[edit]
ESP is the extended (32 bit) pointer to the stack, SUB is a subtraction routine where b is the source and a is the destination.
[/edit]
As for MSVC, this is what you get when you compare the two.. It looks like for (;;) uses less operations!?
Code:while (true)
00413132 xor eax,eax
00413134 inc eax
00413135 test eax,eax
00413137 je main+36h (41314Ch)
{
Sleep(0);
00413139 mov esi,esp
0041313B push 0
0041313D call dword ptr [__imp__Sleep@4 (42B20Ch)]
00413143 cmp esi,esp
00413145 call @ILT+1055(__RTC_CheckEsp) (411424h)
}
0041314A jmp main+1Ch (413132h)
Code:for(;;)
{
Sleep(0);
00413132 mov esi,esp
00413134 push 0
00413136 call dword ptr [__imp__Sleep@4 (42B20Ch)]
0041313C cmp esi,esp
0041313E call @ILT+1055(__RTC_CheckEsp) (411424h)
}
00413143 jmp main+1Ch (413132h)
Finally, proof that MSVC sucks.Quote:
Originally posted by filler_bunny
is what you get when you compare the two.. It looks like for (;;) uses less operations!?
Hmm, interesting. One person finds that the assembly is the same and another finds that the for takes fewer operations. Well, in that case I imagine that with full optimizations they should compile to roughly the same thing, and if not, the difference should be marginal. My summary:
for(;; ) takes less time to type, and is potentially faster (very very slightly). while(true) is easier to read but is potentially slower (very very slightly).
So for the sake of code readability, I suppose I'll stick with while(1)/while(true) unless I'm really really pressed for speed :D Although somebody DID pm me about a compiler warning that for(;; ) is the "more conventional" version of an infinite loop... :rolleyes:
The compiler warning for while(1)/while(true) was mentioned in the other thread. I wonder what is the warning?Quote:
Although somebody DID pm me about a compiler warning that for(;; ) is the "more conventional" version of an infinite loop...
>I wonder what is the warning?
warning C4127: conditional expression is constant
>warning C4127: conditional expression is constant
Hmm, interesting. I hate to go against the accepted wisdom.
I like the while(true) because it seems more intuitive. Unless you've used it before, for(;;) is cryptic. If I saw this for the first time, I would be thinking: Does this mean don't execute the for? Execute the for one time? Execute the for infinite times?
But if the conventional wisdom says use for(;;), then that is what I will use!
Its interesting looking at the difference between the two compilers asm though. It's obvious (and I just retried this with full optimization) that the MS compiler does a check for equality, checking the value of the register against itself (which presumably is where the value of true is kept for the duration of the while loop) when compiling the while loop, but it realises that no such test is required for the for loop as it is empty.
It seems like an odd design decision, not to further optimise the while loop. I guess I may have to pay more attention to my ASM output!
I always used for(;;)... but which of these would be better:
orCode:...
for(;;)
{
if(variable)
break;
else
continue;
}
...
I know all the sloppy differences I left, but that's just some stuff I wrote so you could get the basic idea of my question: is it better to break out of an infinite loop, or is it better to use the variable in a while/do-while loop?Code:...
while(variable)
{...}
...
/me groans as he sees the start of another "break is evil" flame war...
I too am surprised that with optimization enabled MSVC didn't generate identical code, as DevC++ did.Quote:
It seems like an odd design decision, not to further optimise the while loop. I guess I may have to pay more attention to my ASM output!
As for the Major's question, I'll defer to Prelude to provide an answer.:D
No. That is not true. I am using MinGW and for (;;), while (true) and x: goto x; resolved to the exact same statements without code optimization. filler bunny's code is a MS VC++ product.Quote:
Originally posted by Hunter2
Hmm, interesting. One person finds that the assembly is the same and another finds that the for takes fewer operations. Well, in that case I imagine that with full optimizations they should compile to roughly the same thing, and if not, the difference should be marginal. My summary:
for(;; ) takes less time to type, and is potentially faster (very very slightly). while(true) is easier to read but is potentially slower (very very slightly).
I tried to check how it looks with optimizations enabled (but what more to optimize - it's only one jmp?) but that somehow prevented gdb from finding my breakpoint, so I couldn't use the CPU window.
Anyway, that was without optimizations, so at least if you're using a decent compiler (*g*) it will be the same assembler code.
Yes - I suspect that MSVC is probably the only major compiler as used by visitors to this board that does things this way (for this special case).Quote:
No. That is not true. I am using MinGW and for (;;), while (true) and x: goto x; resolved to the exact same statements without code optimization. filler bunny's code is a MS VC++ product.
But I have been wondering why. I suspect that the MSVC compiler is doing the "right" thing, in that the ASM produced is exactly as you would expect from the while loop (i.e. it is evaluating the statement, in this case "true" every time it enters the loop).
But it appears as though most other compilers are doing the "smart" thing in that they are making a special case for a statement that is always going to evaluate to true and resolving the "while(true)" statement to the ASM equivalent of a "for(;;)" loop.
Mm. But I'm using MSVC, so :D But are the tests for MSVC being compiled in debug mode or release mode? I thought that with release mode (i.e. full optimizations) you couldn't use breakpoints or anything :confused:
I've seen this done:
I don't think that looks half bad. And that is all I have to contribute to this thread.Code:#define EVER ;;
for(EVER)
{
// do stuff
}
Lol.