Skip to main content
gamedev.net
🔒 Locked

will return in a loop corrupt stack?

Started by UnshavenBastard 11 replies 1.4k views
Original Post
UnshavenBastard
UnshavenBastard
(If there are differences, I'm interested in specific answers concerning C, C++, C#, Pascal ... ) Hi, I often stumbled upon comments in source codes like "unwind stack"(lamothe) when ie. setting a bool variable to true and break-ing out of a loop instead of just return true;-ing out of the loop:

bool foo()
{
  bool b=false;

  for (int i=0; i<10; ++i)
  {
    if (i==5)
    { b=true;
      break;
    }
  }

 return b;
}

// as opposed to:

bool bar()
{
  for (int i=0; i<10; ++i)
  {
    if (i==5)
      return true;
  }

 return false;
}




Will the latter corrupt the stack in some languages/implementations, or is this guaranteed to work flawlessly everywere? On the one hand, I think allowing such bad things to happen would be silly of language implementers, on the other hand I always had a bad feeling (long before I read such comments) about not "bringing things into the original state" if you know what I mean, and always did and still do it the way like the foo() function is implemented, intiuitively.
@ Mods: The message preview seems to have bugs, my (C, C++, C# was always depicted as (C, C, C#
vNistelrooy
vNistelrooy
No, C++ compilers should just jmp to the end of the function, destroy local objects, unwind the stack and ret correctly.
"C lets you shoot yourself in the foot rather easily. C++ allows you to reuse the bullet!"
Shadowdancer
Shadowdancer
How could that possibly corrupt the stack? It's not like every single construct used its own. A loop runs in the same context as the function it's it, and returning from inside that function can easily "unwind" the stack, no matter where the return is (the stack itself is only defined by a base pointer). However, there apparently are people who think that there should only be exactly one "return" per function, and that it should be at the end.
MrEvil
MrEvil
Quote:
Original post by Shadowdancer
However, there apparently are people who think that there should only be exactly one "return" per function, and that it should be at the end.


Which is a bit dumb considering you have to use a break; to get out of the loop - but oh no, they don't like break; either, so you have to re-arrange the whole loop. Anyway, off topic.

In the first case you add an extra variable and thus needlessly complicate the logic, in my opinion.

Sigh.
private_ctor
private_ctor
for something like this:

for( int i = 0; i < BLAHMOO; i++ ){     if( m_Something.id == i )     {          return true;     }}return false;


Just returning instead of setting a variable then returning that variable is great. Some times you may want to set data based on that loop, break out, then do something afterwards with it though, so you would not just return.

int id = -1;for( int i = 0; i < Blah; i++){     if( Moo.id == i )     {          id = i;          break;     }}     if( id == -1 )          return false;     //otherwise     DoSomethingBasedOnTheID( id );     return true;


This may not answer your question directly, but those are the different scenerios where you would use one over the other.

Returning out of a function in a loop won't affect anything... may even cause a significant speed increase depending on the frequency its called and length of the loop.

Think of return b as "Go back to the function you came from, and bring B with you because that function is waiting for it."

So saying that anywhere in the function won't make a difference to your program. The only thing it will affect is how much of the function it does and the value of your return.

Hope I helped.
-------------------------------Sometimes I ~self();
private_ctor
private_ctor
also, everytime you return no matter where you return from it will take care of the stack and everything just the same.
-------------------------------Sometimes I ~self();
UnshavenBastard
UnshavenBastard
thanks ;)

I just again saw through some old source where it was done this way,
and I thought I just ask other people whether there might be a sound reason.
So, there isn't, fine :-)
Fruny
Fruny
RVO and NRVO shouldn't be affected by the number and placement of your return statements.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
_the_phantom_
_the_phantom_
yes, I probably should have made that clear and stuff... i'm sorry Fruny, dont hurt me [sad]
Basiror
Basiror
returning from inside a loop should not corrupt your stack in any way

returning i.e.: ret in assembler for x86 machines will just return the the address behind the call instruction

1:call func
2:returnstothisposition







70(func):ret #return to 2:


the stack address before a function call is saved in the %ebp register
*stack frame/frame pointer* so you can always address the variables and parameters relative to the %ebp instead of messing around with a ton of addressing instruction which is really a mess if you have ever done this by hand :)

so there s actually no chance that a return withing a loop will corrupt your stack

the only way to corrupt the stack is to play around the local variable's addresses and thus manipulating the frame pointer which might result in
a) strange behaviour
b) segmentation fault
c) without consequences if you are lucky although this is almost never the case

http://www.8ung.at/basiror/theironcross.html
antareus
antareus
Lamothe isn't one to offer good C++ style. ;)
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis
UnshavenBastard
UnshavenBastard
Quote:
Original post by antareus
Lamothe isn't one to offer good C++ style. ;)


well, this is, without any doubt, absolutely correct. [grin]

I just wondered :)
Thanks for the further interesting input.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.