• Create Account

Banner advertising on our site currently available from just \$5!

# To goto or not to goto?

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

93 replies to this topic

### Poll: To goto or not to goto? (149 member(s) have cast votes)

#### How often do you use goto statements?

Percentage of vote: 61.74%

2. Very rarely (43 votes [28.86%])

Percentage of vote: 28.86%

Percentage of vote: 6.04%

4. Quite often (1 votes [0.67%])

Percentage of vote: 0.67%

5. I have made it my quest to use them at least 5 times in each function (2 votes [1.34%])

Percentage of vote: 1.34%

6. The language I use doesn't have this keyword (2 votes [1.34%])

Percentage of vote: 1.34%

Vote Guests cannot vote

### #41szecs  Members   -  Reputation: 2382

Like
0Likes
Like

Posted 09 August 2011 - 06:28 AM

Are you guys serious? Where/what is that complexity you are referring to all the time???

### #42YellPika  Members   -  Reputation: 142

Like
0Likes
Like

Posted 09 August 2011 - 06:32 AM

While I'm at it, I might as well add one more. Since we're using the goto for a quick and dirty exit, why not a return statement then?

loopFuncWithNiceName();
// whatever came after...
// ...

void loopFuncWithNiceName()
{

for (int i=0; i<n; ++i) {
switch (some_array[i]) {
case 0:
//...
break;
case 1:
if (some_condition())
return;// DONE!!!
break;
//...
}
}
}


### #43SillyCow  Members   -  Reputation: 965

Like
0Likes
Like

Posted 09 August 2011 - 06:45 AM

Well, the title says it all I guess

goto | (! goto) = goto.

Since I don't like gotos I would have to say: "To goto and not to goto"

My browser game: Vitrage - A game of stained glass

My android games : Enemies of the Crown &  Killer Bees

### #44elondon  Members   -  Reputation: 242

Like
4Likes
Like

Posted 09 August 2011 - 07:00 AM

If you used a goto in production code I would fire you on the spot.

What a ridiculous statement. I can't imagine you're actually a manager. I've never used a GoTo statement in production code - but I'd certainly hate to work for someone who would fire me if I used a construct they don't like especially without examining the context.

"For any absurd set of thinking, you can probably find a non-zero percentage of the population who is utterly convinced of its truth."

### #45luca-deltodesco  Members   -  Reputation: 637

Like
1Likes
Like

Posted 09 August 2011 - 08:03 AM

While I'm at it, I might as well add one more. Since we're using the goto for a quick and dirty exit, why not a return statement then?

loopFuncWithNiceName();
// whatever came after...
// ...

void loopFuncWithNiceName()
{

for (int i=0; i<n; ++i) {
switch (some_array[i]) {
case 0:
//...
break;
case 1:
if (some_condition())
return;// DONE!!!
break;
//...
}
}
}


Because using a return doesn't give you the opportunity to do any cleaning up before the exit

### #46Cornstalks  Crossbones+   -  Reputation: 6999

Like
0Likes
Like

Posted 09 August 2011 - 10:15 AM

While I'm at it, I might as well add one more. Since we're using the goto for a quick and dirty exit, why not a return statement then?

loopFuncWithNiceName();
// whatever came after...
// ...

void loopFuncWithNiceName()
{

for (int i=0; i<n; ++i) {
switch (some_array[i]) {
case 0:
//...
break;
case 1:
if (some_condition())
return;// DONE!!!
break;
//...
}
}
}


Because using a return doesn't give you the opportunity to do any cleaning up before the exit

I think one of the big problems with this discussion is that there are some assumptions we are each making, but we're not making the same assumptions. For myself, I like C++ and RAII, so I shouldn't really need to do any cleaning up before the exit. However, in other languages or situations, RAII may not be available.

Anyway, I've never used a goto in any of my code, and I don't see myself using it in the future either.
[ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

### #47sindisil  Members   -  Reputation: 386

Like
2Likes
Like

Posted 09 August 2011 - 03:51 PM

I do a lot of C programming.

In C, goto is a good way to handle the cleanup code paths in a function, in much the same way that exceptions might be used in a language that supports exceptions.

Beyond that, goto is very rarely useful to break out of an inner loop.

The whole "never a goto" religion is rather sad. As with virtually any other language feature, they can be misused. Likewise, as with virtually any other language feature, they have their place.

### #48wack  Members   -  Reputation: 1358

Like
0Likes
Like

Posted 09 August 2011 - 05:50 PM

Wow, this goto thing has to be the most discussed non-issue in programming during the last 20 years or so.

### #49Codarki  Members   -  Reputation: 462

Like
1Likes
Like

Posted 11 August 2011 - 04:31 AM

I think the ones against goto always use the worst examples of gotos.

And for that reason, here is an example where I personally think it makes good sense to use goto statements (like a replacement for a small inline function):
static MyClass*MyClass::createInstance(void)
{
MyClass*inst=null;

if(!(inst=new MyClass()))
return null;
if(!(inst->object1=new Object1()))
goto FAILED;
if(!(inst->object2=new Object2()))
goto FAILED;
if(!(inst->object3=new Object3()))
goto FAILED;
if(!(inst->object4=new Object4()))
goto FAILED;

return inst;

FAILED:
{
delete inst->object1;
delete inst->object2;
delete inst->object3;
delete inst->object4;
delete inst;

return null;
}
}


I think you'r example for goto is pretty bad. How can the allocation of those objects fail without throwing an exception?

static MyClass* MyClass::createInstance()
{
MyClass* inst = new MyClass();

if (inst)
{
bool failed = !(inst->object1 = new Object1());
if (!failed)
failed |= !(inst->object2 = new Object2());
if (!failed)
failed |= !(inst->object3 = new Object3());
if (!failed)
failed |= !(inst->object4 = new Object4());

if (failed)
{
delete inst->object1;
delete inst->object2;
delete inst->object3;
delete inst->object4;
delete inst;
inst = 0;
}
}

return inst;
}


If we use C++, lets write C++. Constructors and destructors and all.

MyClass::MyClass()
: object1(new Object1)
: object2(new Object2)
: object3(new Object3)
: object4(new Object4)
{
}

MyClass::~MyClass()
{
delete object1;
delete object2;
delete object3;
delete object4;
}

static MyClass* MyClass::createInstance()
{
return new MyClass();
}

I'd go even further and use std::unique_ptr, so you don't even have to write the destructor.

### #50rip-off  Moderators   -  Reputation: 9753

Like
0Likes
Like

Posted 11 August 2011 - 05:00 AM

If we use C++, lets write C++. Constructors and destructors and all.
...
I'd go even further and use std::unique_ptr, so you don't even have to write the destructor.

You should use std::unique_ptr anyway. In your current code, if Object[2..4] throws during construction the earlier objects will leak.

The alternative is:
MyClass::MyClass()
:
object1(0),
object2(0),
object3(0),
object4(0)
{
try
{
object1 = new Object1;
object2 = new Object2;
object3 = new Object3;
object4 = new Object4;
}
catch(...)
{
delete object4;
delete object3;
delete object2;
delete object1;
throw;
}
}

Ugh.

### #51Codarki  Members   -  Reputation: 462

Like
0Likes
Like

Posted 11 August 2011 - 06:27 AM

You should use std::unique_ptr anyway. In your current code, if Object[2..4] throws during construction the earlier objects will leak.

The alternative is:
...
Ugh.

You are right, I made silly incorrect example (with syntax errors) to criticize some other example. Ofcourse one should use RAII, which solves everything. One could even make the Object[1..4] to be members and not heap allocated, thus reducing the problem to:

MyClass::MyClass()
{
}


### #52Slavik81  Members   -  Reputation: 360

Like
0Likes
Like

Posted 11 August 2011 - 02:35 PM

I think you'r example for goto is pretty bad. How can the allocation of those objects fail without throwing an exception?

http://stackoverflow.com/questions/550451/will-new-return-null-in-any-case

### #53Trienco  Crossbones+   -  Reputation: 2377

Like
0Likes
Like

Posted 11 August 2011 - 10:34 PM

I think you'r example for goto is pretty bad. How can the allocation of those objects fail without throwing an exception?

http://stackoverflow...ull-in-any-case

Which boils down to "because your compiler is old and pre-standard" or "because you explicitely used new(nothrow)". That is relatively unlikely, at least compared to programmers still thinking that if their new ever fails, it will return 0 (heck, every day at work I'm staring at those pointless != NULL checks).
f@dzhttp://festini.device-zero.de

### #54Slavik81  Members   -  Reputation: 360

Like
0Likes
Like

Posted 12 August 2011 - 01:06 AM

Which boils down to "because your compiler is old and pre-standard" or "because you explicitely used new(nothrow)". That is relatively unlikely, at least compared to programmers still thinking that if their new ever fails, it will return 0 (heck, every day at work I'm staring at those pointless != NULL checks).

What do they do if it is NULL? It would be a huge pain to handle allocation failure gracefully at every instance it could occur.

### #55NightCreature83  Crossbones+   -  Reputation: 3581

Like
0Likes
Like

Posted 12 August 2011 - 08:23 AM

I think you'r example for goto is pretty bad. How can the allocation of those objects fail without throwing an exception?

http://stackoverflow...ull-in-any-case

Which boils down to "because your compiler is old and pre-standard" or "because you explicitely used new(nothrow)". That is relatively unlikely, at least compared to programmers still thinking that if their new ever fails, it will return 0 (heck, every day at work I'm staring at those pointless != NULL checks).

Those null checks however could well be valid if your new operator is overriden as the allocation at that point doesn't need to throw when it is not allocating. Most industry places actually don't use execeptions and hence rely on the fact that a valid allocation returns a null pointer.
Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, Mad Max

### #56Tachikoma  Members   -  Reputation: 552

Like
0Likes
Like

Posted 12 August 2011 - 10:19 AM

Which boils down to "because your compiler is old and pre-standard" or "because you explicitely used new(nothrow)". That is relatively unlikely, at least compared to programmers still thinking that if their new ever fails, it will return 0 (heck, every day at work I'm staring at those pointless != NULL checks).

What do they do if it is NULL? It would be a huge pain to handle allocation failure gracefully at every instance it could occur.

The only situation i can think of where new(std::nothrow) should be used is within exception objects (i.e. classes that are based on std::exception, and so on). This may also warrant the use of goto for garbage collection when encountering a == NULL result.
Latest project: Sideways Racing on the iPad

### #57way2lazy2care  Members   -  Reputation: 782

Like
0Likes
Like

Posted 12 August 2011 - 11:04 AM

I think the ones against goto always use the worst examples of gotos.

And for that reason, here is an example where I personally think it makes good sense to use goto statements (like a replacement for a small inline function):
static MyClass*MyClass::createInstance(void)
{
MyClass*inst=null;

if(!(inst=new MyClass()))
return null;
if(!(inst->object1=new Object1()))
goto FAILED;
if(!(inst->object2=new Object2()))
goto FAILED;
if(!(inst->object3=new Object3()))
goto FAILED;
if(!(inst->object4=new Object4()))
goto FAILED;

return inst;

FAILED:
{
delete inst->object1;
delete inst->object2;
delete inst->object3;
delete inst->object4;
delete inst;

return null;
}
}


I think you'r example for goto is pretty bad. How can the allocation of those objects fail without throwing an exception?

static MyClass* MyClass::createInstance()
{
MyClass* inst = new MyClass();

if (inst)
{
bool failed = !(inst->object1 = new Object1());
if (!failed)
failed |= !(inst->object2 = new Object2());
if (!failed)
failed |= !(inst->object3 = new Object3());
if (!failed)
failed |= !(inst->object4 = new Object4());

if (failed)
{
delete inst->object1;
delete inst->object2;
delete inst->object3;
delete inst->object4;
delete inst;
inst = 0;
}
}

return inst;
}


If we use C++, lets write C++. Constructors and destructors and all.

You realize that your code is slower than the example using gotos and arguably less readable. You have an extra variable, 4 extra assignments, and an extra branch vs the goto code

edit: it appears to also fall into the trap of "The Phony Goto Debate" in the Code Complete article. tldr being that using a trivial piece of code you'd never put goto in anyway will more obviously paint goto in a bad light or vice versa the performance gains by using goto may be trivial as the example is trivial to begin with. It's a losing argument from both sides.

### #58Cornstalks  Crossbones+   -  Reputation: 6999

Like
0Likes
Like

Posted 12 August 2011 - 03:12 PM

static MyClass* MyClass::createInstance()
{
MyClass* inst = new MyClass();

if (inst)
{
bool failed = !(inst->object1 = new Object1());
if (!failed)
failed |= !(inst->object2 = new Object2());
if (!failed)
failed |= !(inst->object3 = new Object3());
if (!failed)
failed |= !(inst->object4 = new Object4());

if (failed)
{
delete inst->object1;
delete inst->object2;
delete inst->object3;
delete inst->object4;
delete inst;
inst = 0;
}
}

return inst;
}


If we use C++, lets write C++. Constructors and destructors and all.

You realize that your code is slower than the example using gotos and arguably less readable. You have an extra variable, 4 extra assignments, and an extra branch vs the goto code

Ummmm... Premature optimization? While the code he proposed wasn't what I would call an improvement on the original code, you do realize that the most expensive operation would be the memory allocation, which is something you would try to avoid at all costs if possible in a time critical, tight loop, and the memory allocation should be the focus, if one is going to get into optimizing, and not on the more trivial things, right? The other argument you have (less readable) may be acceptable, however.

Anyway, I'm going to stop here because I don't want to get side tracked and have anyone start flaming or trolling. It was interesting to see everyone else's views on goto.
[ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

### #59Trienco  Crossbones+   -  Reputation: 2377

Like
0Likes
Like

Posted 13 August 2011 - 12:18 AM

Those null checks however could well be valid if your new operator is overriden as the allocation at that point doesn't need to throw when it is not allocating. Most industry places actually don't use execeptions and hence rely on the fact that a valid allocation returns a null pointer.

On projects like that I can see your point, but I assure you, nobody is overriding new or using an old compiler on this project (or actually does anything _useful_ as a result of this check), for example this kind of thing just makes you want to scream:

constructor()
{
if ( (subobjectA = new ObjectA) == NULL)
return;

if ( (subobjectB = new ObjectB) == NULL)
return;

...do more stuff
}


f@dzhttp://festini.device-zero.de

### #60L. Spiro  Crossbones+   -  Reputation: 20409

Like
0Likes
Like

Posted 13 August 2011 - 07:32 AM

I have invented several new programming languages and I never even include the goto keyword.
There is always a more graceful way to handle failures, especially with destructors. C may not have destructors, but there are still ways to securely handle failures, devoid of human faults.

L. Spiro

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

PARTNERS