Particular Example about why should we not use GOTO

A

Alexander Block

Hi Buddies,

I have read a lot of stuffs regarding not using GOTO statements to opt
a good programming style [Refhttp://david.tribble.com/text/goto.html].
Can anybody give a particular lines of code which shows harmfullness
of GOTO.

SoftEast...

I use it in Mobile Development for error handling and clean up.
Normally I would use
exceptions for that, but this would be to much overhead for mobile
phones. Here is an example:

bool DoSomething() //returns false on failure
{
SomeObject* obj1 = NULL, obj2 = NULL;

obj2 = new SomeObject();
if(!ThisMayFail(obj1))
goto failed;

obj2 = new SomeObject();
if(!ThisMayFail(obj2))
goto failed;

return true;

failed:
if(obj1 != NULL)
delete obj1;
if(obj2 != NULL)
delete obj2;
return false;
}

I think this kind of clean up technique is easy to understand and
maintain.
 
A

Alexander Block

Hi Buddies,
I have read a lot of stuffs regarding not using GOTO statements to opt
a good programming style [Refhttp://david.tribble.com/text/goto.html].
Can anybody give a particular lines of code which shows harmfullness
of GOTO.
SoftEast...

I use it in Mobile Development for error handling and clean up.
Normally I would use
exceptions for that, but this would be to much overhead for mobile
phones. Here is an example:

bool DoSomething() //returns false on failure
{
SomeObject* obj1 = NULL, obj2 = NULL;

obj2 = new SomeObject();
if(!ThisMayFail(obj1))
goto failed;

obj2 = new SomeObject();
if(!ThisMayFail(obj2))
goto failed;

return true;

failed:
if(obj1 != NULL)
delete obj1;
if(obj2 != NULL)
delete obj2;
return false;

}

I think this kind of clean up technique is easy to understand and
maintain.

Oh...I see you requested a HARMFULL and not USEFULL example :D
If you want it harmfull, remove the NULL initialization in the first
line of the method ;)
 
A

Alexander Block

Hi Buddies,
I have read a lot of stuffs regarding not using GOTO statements to opt
a good programming style [Refhttp://david.tribble.com/text/goto.html].
Can anybody give a particular lines of code which shows harmfullness
of GOTO.
SoftEast...
I use it in Mobile Development for error handling and clean up.
Normally I would use
exceptions for that, but this would be to much overhead for mobile
phones. Here is an example:
bool DoSomething() //returns false on failure
{
SomeObject* obj1 = NULL, obj2 = NULL;
obj2 = new SomeObject();
if(!ThisMayFail(obj1))
goto failed;
obj2 = new SomeObject();
if(!ThisMayFail(obj2))
goto failed;
return true;
failed:
if(obj1 != NULL)
delete obj1;
if(obj2 != NULL)
delete obj2;
return false;

I think this kind of clean up technique is easy to understand and
maintain.

Oh...I see you requested a HARMFULL and not USEFULL example :D
If you want it harmfull, remove the NULL initialization in the first
line of the method ;)

A better example for harmfull gotos:

class CTest
{
public:
char* str;

CTest()
{
str = "Initialized correctly";
}

void UseMe()
{
OutputDebugStringA(str);
}
};

int main()
{
CTest test1;

goto harmfull;

CTest test2;

harmfull:
test1.UseMe();
test2.UseMe();

return 0;
}

The goto will skip the constructor of CTest here. The compiler is not
able to check that, so you have an object that looks ok, but is not
initialized. In most cases, the above example will crash on
test2.UseMe(), because test2.str has an uninitialized value.
 
G

Gavin Deane

Hi Buddies,
I have read a lot of stuffs regarding not using GOTO statements to opt
a good programming style [Refhttp://david.tribble.com/text/goto.html].
Can anybody give a particular lines of code which shows harmfullness
of GOTO.
SoftEast...

I use it in Mobile Development for error handling and clean up.
Normally I would use
exceptions for that, but this would be to much overhead for mobile
phones. Here is an example:

bool DoSomething() //returns false on failure
{
SomeObject* obj1 = NULL, obj2 = NULL;

obj2 = new SomeObject();
if(!ThisMayFail(obj1))
goto failed;

obj2 = new SomeObject();
if(!ThisMayFail(obj2))
goto failed;

return true;

failed:
if(obj1 != NULL)
delete obj1;
if(obj2 != NULL)
delete obj2;
return false;

}

I think this kind of clean up technique is easy to understand and
maintain.

Any reason RAII is too much overhead for mobile phones? That would
seem the natural solution in this case.

Gavin Deane
 
R

Robert Bauck Hamar

Alexander said:
On 29 Mrz., 09:54, "SoftEast" <[email protected]> wrote:
Hi Buddies,
I have read a lot of stuffs regarding not using GOTO statements to
opt a good programming style
[Refhttp://david.tribble.com/text/goto.html]. Can anybody give a
particular lines of code which shows harmfullness of GOTO.
SoftEast...

I use it in Mobile Development for error handling and clean up.
Normally I would use
exceptions for that, but this would be to much overhead for mobile
phones. Here is an example:
bool DoSomething() //returns false on failure
{
SomeObject* obj1 = NULL, obj2 = NULL;
obj2 = new SomeObject();
if(!ThisMayFail(obj1))
goto failed;
obj2 = new SomeObject();
if(!ThisMayFail(obj2))
goto failed;
return true;
failed:
if(obj1 != NULL)
delete obj1;
if(obj2 != NULL)
delete obj2;
return false;

I think this kind of clean up technique is easy to understand and
maintain.

Oh...I see you requested a HARMFULL and not USEFULL example :D
If you want it harmfull, remove the NULL initialization in the first
line of the method ;)

A better example for harmfull gotos:

class CTest
{
public:
char* str;

CTest()
{
str = "Initialized correctly";
}

void UseMe()
{
OutputDebugStringA(str);
}
};

int main()
{
CTest test1;

goto harmfull;

CTest test2;

harmfull:
test1.UseMe();
test2.UseMe();

return 0;
}

The goto will skip the constructor of CTest here.

No, the code should not compile. You are not allowed to skip the
initialization of an object
 
A

Alexander Block

Alexander said:
Hi Buddies,
I have read a lot of stuffs regarding not using GOTO statements to
opt a good programming style
[Refhttp://david.tribble.com/text/goto.html]. Can anybody give a
particular lines of code which shows harmfullness of GOTO.
SoftEast...
I use it in Mobile Development for error handling and clean up.
Normally I would use
exceptions for that, but this would be to much overhead for mobile
phones. Here is an example:
bool DoSomething() //returns false on failure
{
SomeObject* obj1 = NULL, obj2 = NULL;
obj2 = new SomeObject();
if(!ThisMayFail(obj1))
goto failed;
obj2 = new SomeObject();
if(!ThisMayFail(obj2))
goto failed;
return true;
failed:
if(obj1 != NULL)
delete obj1;
if(obj2 != NULL)
delete obj2;
return false;
}
I think this kind of clean up technique is easy to understand and
maintain.
Oh...I see you requested a HARMFULL and not USEFULL example :D
If you want it harmfull, remove the NULL initialization in the first
line of the method ;)
A better example for harmfull gotos:
class CTest
{
public:
char* str;
CTest()
{
str = "Initialized correctly";
}
void UseMe()
{
OutputDebugStringA(str);
}
};
int main()
{
CTest test1;
goto harmfull;
CTest test2;

return 0;
}
The goto will skip the constructor of CTest here.

No, the code should not compile. You are not allowed to skip the
initialization of an object

--
Robert Bauck Hamar
Semikolon markerer en litt kortere pause enn punktum; det kan bare
stå mellom selvstendige setninger. Det er en moderne uskikk å bruke
semikolon istedenfor kolon. Følg ikke den uskikken!

It is definitely compilable (at least in Visual Studio 2003) and
result in a crash as described.

To Gavin
I need to reduce the resulting binary size as much as possible.
Exception handling would increase it too much. Even if it would be
only some kb, it is too much. I have 135kb with all resources in my
current application which runs on nearly all phones (BREW). On some of
the phones there is only 10kb heap leaft after startup...so increasing
the the binary size by only 5kb would make it impossible to support
the low end phones.
 
P

peter koch

Hi Buddies,
I have read a lot of stuffs regarding not using GOTO statements to opt
a good programming style [Refhttp://david.tribble.com/text/goto.html].
Can anybody give a particular lines of code which shows harmfullness
of GOTO.
SoftEast...

I use it in Mobile Development for error handling and clean up.
Normally I would use
exceptions for that, but this would be to much overhead for mobile
phones. Here is an example:

bool DoSomething() //returns false on failure
{
SomeObject* obj1 = NULL, obj2 = NULL;

obj2 = new SomeObject();
if(!ThisMayFail(obj1))
goto failed;

obj2 = new SomeObject();
if(!ThisMayFail(obj2))
goto failed;

return true;

failed:
if(obj1 != NULL)
delete obj1;
if(obj2 != NULL)
delete obj2;
return false;

}

I think this kind of clean up technique is easy to understand and
maintain.

I would write the above as


bool DoSomething()
{
SomeObject obj1;
if (ThisMayFail(obj1))
{
SomeObject Obj2;
return ThisMayFail(Obj2);
}
return false;
}

Or (in case pointers are needed)

bool DoSomething()
{
std::auto_ptr<SomeObject obj1(new SomeObject);
if (ThisMayFail(obj1.get()))
{
std::auto_ptr<SomeObject obj2(new SomeObject);
if (ThisMayFail(Obj2))
{
// presumably more code here
return true;
}
}
return false;
}

No reason for gotos here, and I recommend using them very sparingly (I
remember only a handful of gotos in my carreer, and then it was C, not
C++).

/Peter
 
R

Robert Bauck Hamar

Alexander said:
It is definitely compilable (at least in Visual Studio 2003) and
result in a crash as described.

Then your compiler is buggy. The standard states that this is ill-formed.

$ g++ -pedantic -ansi -Wall goto.cc
goto.cc: In function 'int main()':
goto.cc:31: error: jump to label 'harmfull'
goto.cc:27: error: from here
goto.cc:29: error: crosses initialization of 'CTest test2'
$
 
G

Gavin Deane

It is definitely compilable (at least in Visual Studio 2003) and
result in a crash as described.

Comeau online rejects it, as does MS Visual Studio 2005.
<OT>
Although, if I enable language extensions, the MS compiler changes
from treating it as an error to a warning. Perhaps the 2003 version
has the same extension.
To Gavin
I need to reduce the resulting binary size as much as possible.
Exception handling would increase it too much. Even if it would be
only some kb, it is too much. I have 135kb with all resources in my
current application which runs on nearly all phones (BREW). On some of
the phones there is only 10kb heap leaft after startup...so increasing
the the binary size by only 5kb would make it impossible to support
the low end phones.

<Rearranging a bit for context>

You had

I wasn't suggesting anything to do with exceptions, just using RAII to
manage the memory automatically and do away with the need for any
cleanup code at all. Definitely more maintenace friendly. In this
example, std::auto_ptr would seem to fit the bill, as suggested
elsethread by Peter Koch.

Gavin Deane
 
J

Jim Langston

Alexander Block said:
Hi Buddies,

I have read a lot of stuffs regarding not using GOTO statements to opt
a good programming style [Refhttp://david.tribble.com/text/goto.html].
Can anybody give a particular lines of code which shows harmfullness
of GOTO.

SoftEast...

I use it in Mobile Development for error handling and clean up.
Normally I would use
exceptions for that, but this would be to much overhead for mobile
phones. Here is an example:

bool DoSomething() //returns false on failure
{
SomeObject* obj1 = NULL, obj2 = NULL;

obj2 = new SomeObject();
if(!ThisMayFail(obj1))
goto failed;

obj2 = new SomeObject();
if(!ThisMayFail(obj2))
goto failed;

return true;

failed:
if(obj1 != NULL)
delete obj1;
if(obj2 != NULL)
delete obj2;
return false;
}

I think this kind of clean up technique is easy to understand and
maintain.

bool DoSomething() //returns false on failure
{
SomeObject* obj1 = NULL, obj2 = NULL;

try
{
obj2 = new SomeObject();
if(!ThisMayFail(obj1))
throw;

obj2 = new SomeObject();
if(!ThisMayFail(obj2))
throw;

return true;
}
catch(...)
{
if(obj1 != NULL)
delete obj1;
if(obj2 != NULL)
delete obj2;
return false;
}
}

Undserstanding that this code isn't deleting obj1 and obj2 on success, just
as the original code wasn't.

There are always alternatives to useing goto.

Of course, you may have intended success to fall through to the cleanup, but
it didn't because you were returning before you got there. Which is the
problem with goto's, it obfuscates code.
 
V

Victor Bazarov

Jim said:
Alexander Block said:
Hi Buddies,

I have read a lot of stuffs regarding not using GOTO statements to
opt a good programming style
[Refhttp://david.tribble.com/text/goto.html]. Can anybody give a
particular lines of code which shows harmfullness of GOTO.

SoftEast...

I use it in Mobile Development for error handling and clean up.
Normally I would use
exceptions for that, but this would be to much overhead for mobile
phones. Here is an example:

bool DoSomething() //returns false on failure
{
SomeObject* obj1 = NULL, obj2 = NULL;

obj2 = new SomeObject();
if(!ThisMayFail(obj1))
goto failed;

obj2 = new SomeObject();
if(!ThisMayFail(obj2))
goto failed;

return true;

failed:
if(obj1 != NULL)
delete obj1;
if(obj2 != NULL)
delete obj2;
return false;
}

I think this kind of clean up technique is easy to understand and
maintain.

bool DoSomething() //returns false on failure
{
SomeObject* obj1 = NULL, obj2 = NULL;

try
{
obj2 = new SomeObject();
if(!ThisMayFail(obj1))
throw;

'throw' without a value is only useful inside a 'catch' clause.
It re-throws the exception caught. You should probably write
'throw 42' here.
obj2 = new SomeObject();
if(!ThisMayFail(obj2))
throw;

Same here.
return true;
}
catch(...)
{
if(obj1 != NULL)
delete obj1;
if(obj2 != NULL)
delete obj2;

There is no need to check for NULL before using 'delete'. Drop
those and you will have an even cleaner function.
return false;
}
}

Undserstanding that this code isn't deleting obj1 and obj2 on
success, just as the original code wasn't.

There are always alternatives to useing goto.

Of course, you may have intended success to fall through to the
cleanup, but it didn't because you were returning before you got
there. Which is the problem with goto's, it obfuscates code.

Exceptions are no better when obfuscation is concerned. With 'goto'
I can at least expect that the label is in the same function. With
exception handling, the thrown exception can be in a different
module altogether.

You're correct, there are alternatives. Not all of them are
available in any environment. Some embedded programs (I heard)
cannot contain exception handling.

Now, if I use 'auto_ptr', I can rewrite the 'DoSomething' as

bool DoSomething() //returns false on failure
{
auto_ptr<SomeObject> obj1(new SomeObject());
if(!ThisMayFail(obj1))
return false; // deletes obj1

auto_ptr<SomeObject> obj2(new SomeObject());
if(!ThisMayFail(obj2))
return false; // deletes obj2 _and_ obj1

obj1.release(); // obj1 forgets about the object it held
obj2.release(); // obj2 forgets about the object it held

return true; // deletes nothing
}

V
 
V

Victor Bazarov

Juha said:
I don't have examples and I personally don't hate goto if it's
used properly.
The thing is, however, that in all the years and the tens of
thousands (could even be over 100 thousands) of lines of C++ code
I have written I don't remember needing a 'goto' even once.

In my experience clean, high-quality, well-written C++ code just
doesn't need 'goto'. There's no reason to use it. IMO if you find
a situation where 'goto' appears to be the best solution, that's
usually just a sign that you are taking the wrong approach at the
solution and that there's a much better, cleaner and safer solution.

"Absence of evidence is not evidence of absence". Answers to both
of your positions. Oh, and look it up (say, on Google), makes a good
conversation topic.

Also, Juha, consider this: did you form your opinion (I'm referring
to your sentence that starts with "IMO") based on your experience (of
never needing 'goto'), or did you happen to fall prey to prejudice
[against 'goto'] to avoid it and hence always managed to rewrite the
code so that 'goto' isn't used? I am not asking to respond, I am
just asking to think about it.

V
 
A

Alexander Block

I would write the above as

bool DoSomething()
{
SomeObject obj1;
if (ThisMayFail(obj1))
{
SomeObject Obj2;
return ThisMayFail(Obj2);
}
return false;

}

Or (in case pointers are needed)

bool DoSomething()
{
std::auto_ptr<SomeObject obj1(new SomeObject);
if (ThisMayFail(obj1.get()))
{
std::auto_ptr<SomeObject obj2(new SomeObject);
if (ThisMayFail(Obj2))
{
// presumably more code here
return true;
}
}
return false;

}

No reason for gotos here, and I recommend using them very sparingly (I
remember only a handful of gotos in my carreer, and then it was C, not
C++).

/Peter

You're right, RAII (didn't know the meaning before) and auto_ptr is
the better the solution. But I also avoided the stl and own templates
in that project, which makes auto_ptr impossible.
Well, looks like I avoided so much C++ features in that project that I
may not call it a C++ project, which makes my goto example a bit
useless ;)
 
J

Juha Nieminen

SoftEast said:
Can anybody give a particular lines of code which shows harmfullness
of GOTO.

I don't have examples and I personally don't hate goto if it's
used properly.
The thing is, however, that in all the years and the tens of
thousands (could even be over 100 thousands) of lines of C++ code
I have written I don't remember needing a 'goto' even once.

In my experience clean, high-quality, well-written C++ code just
doesn't need 'goto'. There's no reason to use it. IMO if you find
a situation where 'goto' appears to be the best solution, that's
usually just a sign that you are taking the wrong approach at the
solution and that there's a much better, cleaner and safer solution.
 
T

twomers

Victor said:
Also, Juha, consider this: did you form your opinion (I'm referring
to your sentence that starts with "IMO") based on your experience (of
never needing 'goto'), or did you happen to fall prey to prejudice
[against 'goto'] to avoid it and hence always managed to rewrite the
code so that 'goto' isn't used? I am not asking to respond, I am
just asking to think about it.

I do know the "good uses" of 'goto'. However, I have never found
myself needing to use it.
I have found, however, that usually the alternative clean solution
to using goto is better encapsulation. The thing is that the "good
use" of 'goto' often deals with resource management/freeing, and
I have found that encapsulation is a much safer and cleaner way for
resource handling, and a good implementation actually makes the code
better, safer and more reusable.

Just as a very small example to visualize what I mean: When you
handle C-style "strings" (ie. dynamically allocated char arrays)
in a function, you constantly need to be very careful to free
everything you have allocated at each exit point of the function.
Because it's tedious to write all the same freeing calls at each
exit point, 'goto' is sometimes used to jump to the end of the
function where everything is freed.
However, compare that to using std::string in C++: You don't have
to worry about freeing them because they will be automatically freed
when the function is exited. You don't need to use 'goto'. At the
same time the function becomes cleaner, easier to read and, most
importantly, *safer*.

And no, I'm not saying that's the only "good use" of 'goto'.
I just wrote one example of what I'm talking about.

The only useful use of goto that I've come across is as a quick exit
from deep loop nesting, but that comes with a lot of health warnings
attached! You have to be very careful about whether or not you have
dynamically allocated something before you use the goto, or else you
will have memory leaks (this was probably brought up earlier), and if
that portion of code is used a lot (say within a commonly called
function or something), they will become significant.

Gotos can be viewed as forcefully constructing a loop (obviously this
is only within some circumstances), but there are better ways of doing
this than using loops - while() is a good alternative. for() too. And
if you want to skip a portion of code because it's not relevant, just
use an if(), you'd use an if() for the goto anyway:


if ( circumstance == true )
goto end;
// CODE to skip [...]
end:;

if ( circumstance != true )
{
// CODE that you skip if it is true
}
// This would be where end:; would go then.
 
J

Juha Nieminen

Victor said:
Also, Juha, consider this: did you form your opinion (I'm referring
to your sentence that starts with "IMO") based on your experience (of
never needing 'goto'), or did you happen to fall prey to prejudice
[against 'goto'] to avoid it and hence always managed to rewrite the
code so that 'goto' isn't used? I am not asking to respond, I am
just asking to think about it.

I do know the "good uses" of 'goto'. However, I have never found
myself needing to use it.
I have found, however, that usually the alternative clean solution
to using goto is better encapsulation. The thing is that the "good
use" of 'goto' often deals with resource management/freeing, and
I have found that encapsulation is a much safer and cleaner way for
resource handling, and a good implementation actually makes the code
better, safer and more reusable.

Just as a very small example to visualize what I mean: When you
handle C-style "strings" (ie. dynamically allocated char arrays)
in a function, you constantly need to be very careful to free
everything you have allocated at each exit point of the function.
Because it's tedious to write all the same freeing calls at each
exit point, 'goto' is sometimes used to jump to the end of the
function where everything is freed.
However, compare that to using std::string in C++: You don't have
to worry about freeing them because they will be automatically freed
when the function is exited. You don't need to use 'goto'. At the
same time the function becomes cleaner, easier to read and, most
importantly, *safer*.

And no, I'm not saying that's the only "good use" of 'goto'.
I just wrote one example of what I'm talking about.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,906
Latest member
SkinfixSkintag

Latest Threads

Top