By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,645 Members | 1,065 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,645 IT Pros & Developers. It's quick & easy.

GOTO statement and return results way

P: n/a
Hello,

I have a question about the infamous GOTO statement and the way to return a
result from a sub:
I have a sub that has to make some calls to external COM methods, and
because these methods can fail I have to check them to be running ok, like
this:

sub method(byval param1 as integer, ...., BYREF result as String)

dim ...
..
..
result=callCOM1(params)
if result=-1 then 'bad result
result="callCOM1 failed, dude!"
GOTO ENDPOINT
..
..
result=callCOM2(params)
if result=-1 then 'bad result
result="callCOM2 failed, dude!"
GOTO ENDPOINT
..
..
ENDPOINT:

'make some dispose, and additional tasks

end sub

Then, the CALLER function will check the RESULT var and will proceed as
required.
I choosed a sub instead of a function as I think that a function have to
return other information than "function executed ok or not", as datasets,
application objects etc.

The second doubt is the GOTO: you know, it is a bad wound in code, but I
use it as a fast way to exit the sub.

How would you change all this to be more structured and aesthetic ? maybe
creating a sub where all the dispose is done ? --then I'd have to pass all
the vars to be disposed or make them public/friend 8-( ...

Thanks in advance,

Roger Tranchez
MCTS
..NET 2005 and DB developer

Jan 14 '08 #1
Share this Question
Share on Google+
11 Replies


P: n/a
Roger,

What you want is from before 1970.

Just Create an, what you call "Endpoint function", call that end then use
"Return" that has the same effect.

Cor

"Roger Tranchez" <ru*****@community.nospamschreef in bericht
news:52**********************************@microsof t.com...
Hello,

I have a question about the infamous GOTO statement and the way to return
a
result from a sub:
I have a sub that has to make some calls to external COM methods, and
because these methods can fail I have to check them to be running ok, like
this:

sub method(byval param1 as integer, ...., BYREF result as String)

dim ...
.
.
result=callCOM1(params)
if result=-1 then 'bad result
result="callCOM1 failed, dude!"
GOTO ENDPOINT
.
.
result=callCOM2(params)
if result=-1 then 'bad result
result="callCOM2 failed, dude!"
GOTO ENDPOINT
.
.
ENDPOINT:

'make some dispose, and additional tasks

end sub

Then, the CALLER function will check the RESULT var and will proceed as
required.
I choosed a sub instead of a function as I think that a function have to
return other information than "function executed ok or not", as datasets,
application objects etc.

The second doubt is the GOTO: you know, it is a bad wound in code, but I
use it as a fast way to exit the sub.

How would you change all this to be more structured and aesthetic ? maybe
creating a sub where all the dispose is done ? --then I'd have to pass
all
the vars to be disposed or make them public/friend 8-( ...

Thanks in advance,

Roger Tranchez
MCTS
.NET 2005 and DB developer

Jan 14 '08 #2

P: n/a
The second doubt is the GOTO: you know, it is a bad wound in code, but I
use it as a fast way to exit the sub.
How would you change all this to be more structured and aesthetic ?
When I have some functions to perform in sequence and I want to quit on the
first failure, I use one of two constructs - 'nested if' or 'do once'. I
prefer 'nested if' when I have few functions, I prefer 'do once' when I have
many.

Assuming the functions are x1, x2, and x3, 'nested if' is:

x1
If Success Then
x2
If Success Then
x3
If Success Then
' processing here for all success
End If
End If
End If

'Do Once':

Do
x1
If Fail Then Exit Do
x2
If Fail Then Exit Do
x3
If Fail Then Exit Do
' processing here for all success
Loop Until True

These constructs compile to code that is similar to yours with 'goto
endpoint', but the source code avoids goto's and label's. I prefer them over
goto's because I think they are easier to understand for a new person or for
you when you come back to the code after not looking at it for a few months.

Jan 14 '08 #3

P: n/a

--
Roger Tranchez
MCTS
..NET 2005 and DB developer
"AMercer" wrote:
The second doubt is the GOTO: you know, it is a bad wound in code, but I
use it as a fast way to exit the sub.
How would you change all this to be more structured and aesthetic ?

When I have some functions to perform in sequence and I want to quit on the
first failure, I use one of two constructs - 'nested if' or 'do once'. I
prefer 'nested if' when I have few functions, I prefer 'do once' when I have
many.

Assuming the functions are x1, x2, and x3, 'nested if' is:

x1
If Success Then
x2
If Success Then
x3
If Success Then
' processing here for all success
End If
End If
End If

'Do Once':

Do
x1
If Fail Then Exit Do
x2
If Fail Then Exit Do
x3
If Fail Then Exit Do
' processing here for all success
Loop Until True

These constructs compile to code that is similar to yours with 'goto
endpoint', but the source code avoids goto's and label's. I prefer them over
goto's because I think they are easier to understand for a new person or for
you when you come back to the code after not looking at it for a few months.
Jan 14 '08 #4

P: n/a
Hello,

Thanks for your answer.

I kew that about nested ifs, but I don't like it because it adds complexity
to code.

I found the second method more elegant: do.. loop until true, I LIKE it.
But, risking to be too fussy, this "loop until true" trick seems just a bit
round-about 8-D

What do you think about the first question ? : to return if a procedure has
done well its work you 'd use a FUNCTION that returns the result code for
the operation, or a sub that, by means of a byref parameter returns the
result code ?

Wich is the paradigm for types of result codes: Strings, integers, custom
objects ?

Thanks again,
Roger Tranchez
MCTS
..NET 2005 and DB developer
"AMercer" wrote:
The second doubt is the GOTO: you know, it is a bad wound in code, but I
use it as a fast way to exit the sub.
How would you change all this to be more structured and aesthetic ?

When I have some functions to perform in sequence and I want to quit on the
first failure, I use one of two constructs - 'nested if' or 'do once'. I
prefer 'nested if' when I have few functions, I prefer 'do once' when I have
many.

Assuming the functions are x1, x2, and x3, 'nested if' is:

x1
If Success Then
x2
If Success Then
x3
If Success Then
' processing here for all success
End If
End If
End If

'Do Once':

Do
x1
If Fail Then Exit Do
x2
If Fail Then Exit Do
x3
If Fail Then Exit Do
' processing here for all success
Loop Until True

These constructs compile to code that is similar to yours with 'goto
endpoint', but the source code avoids goto's and label's. I prefer them over
goto's because I think they are easier to understand for a new person or for
you when you come back to the code after not looking at it for a few months.
Jan 14 '08 #5

P: n/a

--
Roger Tranchez
MCTS
..NET 2005 and DB developer
"AMercer" wrote:
The second doubt is the GOTO: you know, it is a bad wound in code, but I
use it as a fast way to exit the sub.
How would you change all this to be more structured and aesthetic ?

When I have some functions to perform in sequence and I want to quit on the
first failure, I use one of two constructs - 'nested if' or 'do once'. I
prefer 'nested if' when I have few functions, I prefer 'do once' when I have
many.

Assuming the functions are x1, x2, and x3, 'nested if' is:

x1
If Success Then
x2
If Success Then
x3
If Success Then
' processing here for all success
End If
End If
End If

'Do Once':

Do
x1
If Fail Then Exit Do
x2
If Fail Then Exit Do
x3
If Fail Then Exit Do
' processing here for all success
Loop Until True

These constructs compile to code that is similar to yours with 'goto
endpoint', but the source code avoids goto's and label's. I prefer them over
goto's because I think they are easier to understand for a new person or for
you when you come back to the code after not looking at it for a few months.
Jan 14 '08 #6

P: n/a
What do you think about the first question ? : to return if a procedure has
done well its work you 'd use a FUNCTION that returns the result code for
the operation, or a sub that, by means of a byref parameter returns the
result code ?
I don't have a problem with functions that return status indicators, and I
don't have a problem with subs/functions that have byref parameters for
returning results. Fxcop guides against byref parameters, and I seem to
recall reading somewhere that Fxcop or MS guides against returning status
codes (I think an MS programming guideline, but memory fails). If the
setting is simple, I don't accept such guidance. If the setting is complex
(many functions, many function outputs, etc), then I would create a class
that encapsulates all the complexity.

Jan 14 '08 #7

P: n/a
I think the point that has been missed is that you need to do some other
processing between the target of the 'goto' and the actual end of the 'sub'.

A mechanism that has been designed exactly for this purpose is the
Try...Finally...End Try construct.

In your case it would become something like:

sub method(byval param1 as integer, ...., BYREF result as String)

Try
Jan 14 '08 #8

P: n/a
I think there is nothing wrong with your code. Avoiding GOTO at all costs is
considered harmful :-) Why otherwise competent programmers go to such lengths
to avoid GOTO is beyond me.

At the risk of starting a flame war, I would highly recommend AGAINST the
two suggestions by AMercer.

1) Nested IF
This one is okay provided you don't have too many conditions. Once you get
more than about five IFs though, the indenting makes the code harder, not
easier to read. (five IFs = 20 spaces indent = 25% whitespace on a 80 column
screen)

2) Do...Loop Until True
This is an abomination and any programmer that uses such a construct is
avoiding GOTO for avoidance' sake. THERE IS NO LOOP, so the use of Do...Loop
in this way is a misuse of the command. Furthermore the use of Exit Do in
this construct is as an unconditional jump. There is already an unconditional
jump command, and that command is GOTO. If indenting is so important to you,
turn off pretty code and indent it yourself.

I'm not saying we should all start using GOTO everywhere, but it certainly
should be used when:
* You have a transaction consisting of multiple steps
* If any step fails, the transaction as a whole fails, and you do not need
to perform the subsequent steps
* Whether or not the transaction fails, some cleanup operations are required

See also: http://slashdot.org/~SurturZ/journal/145833

The original "considered harmful" article by Dijkstra published almost 40
years ago! It is barely relevant today, if it was ever relevant. Back then,
computer memory was measured in KILObytes and the memory (stack) usage
implications of GOSUB/SUB were not inconsiderable; so GOTO might have been
required for those reasons (rewriting code to save a SINGLE BYTE of memory
was commonplace back then). Code is sometimes hard to read by necessity.

--
David Streeter
Synchrotech Software
Sydney Australia
"AMercer" wrote:
The second doubt is the GOTO: you know, it is a bad wound in code, but I
use it as a fast way to exit the sub.
How would you change all this to be more structured and aesthetic ?

When I have some functions to perform in sequence and I want to quit on the
first failure, I use one of two constructs - 'nested if' or 'do once'. I
prefer 'nested if' when I have few functions, I prefer 'do once' when I have
many.

Assuming the functions are x1, x2, and x3, 'nested if' is:

x1
If Success Then
x2
If Success Then
x3
If Success Then
' processing here for all success
End If
End If
End If

'Do Once':

Do
x1
If Fail Then Exit Do
x2
If Fail Then Exit Do
x3
If Fail Then Exit Do
' processing here for all success
Loop Until True

These constructs compile to code that is similar to yours with 'goto
endpoint', but the source code avoids goto's and label's. I prefer them over
goto's because I think they are easier to understand for a new person or for
you when you come back to the code after not looking at it for a few months.
Jan 16 '08 #9

P: n/a
"Exit Try" instead of "Return" might be a bit easier to read, and allows you
to have code after the Try block (eg. if the Try block is itself in an IF
block or somesuch).

--
David Streeter
Synchrotech Software
Sydney Australia
"Stephany Young" wrote:
I think the point that has been missed is that you need to do some other
processing between the target of the 'goto' and the actual end of the 'sub'.

A mechanism that has been designed exactly for this purpose is the
Try...Finally...End Try construct.

In your case it would become something like:

sub method(byval param1 as integer, ...., BYREF result as String)

Try
.
result=callCOM1(params)
if result=-1 then
result="callCOM1 failed, dude!"
Return
End If
.
result=callCOM2(params)
if result=-1 then
result="callCOM2 failed, dude!"
Return
End If
.
Finally
'make some dispose, and additional tasks
End Try

end sub

Even though a 'return' theoretically returns immediately, the code in the
'Finally' block WILL be exected before the 'sub' actually returns.

That said, although I have no actual evidence to support it, my instinct
tells me that returning a value from a Function is probably more efficient
than using a ByRef parameter. If it is not more efficient, then it is, in my
opinion, more elegant and maintainable, both for the caller and callee. They
way I would code it is:

Function method(byval param1 as integer, ....) As String

Try
Dim result as Integer
.
result=callCOM1(params)
if result=-1 then Return "callCOM1 failed, dude!"
.
result=callCOM2(params)
if result=-1 then Return "callCOM2 failed, dude!"
.
Return result.ToString()
Finally
'make some dispose, and additional tasks
End Try

End Function
"Roger Tranchez" <ru*****@community.nospamwrote in message
news:43**********************************@microsof t.com...
Hello,

Thanks for your answer.

I kew that about nested ifs, but I don't like it because it adds
complexity
to code.

I found the second method more elegant: do.. loop until true, I LIKE it.
But, risking to be too fussy, this "loop until true" trick seems just a
bit
round-about 8-D

What do you think about the first question ? : to return if a procedure
has
done well its work you 'd use a FUNCTION that returns the result code for
the operation, or a sub that, by means of a byref parameter returns the
result code ?

Wich is the paradigm for types of result codes: Strings, integers, custom
objects ?

Thanks again,
Roger Tranchez
MCTS
.NET 2005 and DB developer
"AMercer" wrote:
The second doubt is the GOTO: you know, it is a bad wound in code, but
I
use it as a fast way to exit the sub.
How would you change all this to be more structured and aesthetic ?

When I have some functions to perform in sequence and I want to quit on
the
first failure, I use one of two constructs - 'nested if' or 'do once'. I
prefer 'nested if' when I have few functions, I prefer 'do once' when I
have
many.

Assuming the functions are x1, x2, and x3, 'nested if' is:

x1
If Success Then
x2
If Success Then
x3
If Success Then
' processing here for all success
End If
End If
End If

'Do Once':

Do
x1
If Fail Then Exit Do
x2
If Fail Then Exit Do
x3
If Fail Then Exit Do
' processing here for all success
Loop Until True

These constructs compile to code that is similar to yours with 'goto
endpoint', but the source code avoids goto's and label's. I prefer them
over
goto's because I think they are easier to understand for a new person or
for
you when you come back to the code after not looking at it for a few
months.

Jan 16 '08 #10

P: n/a
Now that's just getting picky for the sake of getting picky.

As you can clearly see, there is NO code after the Try...Finally...End Try
block so your e. is completely irrelevant.

In the context, changing the Return ... to Exit Try would add unecessary
complexity, because one would have to add Return ... after the End Try
which, in turn, would necessitate moving the declaration of _result to
before the Try.

As you can see, that is totally unecessary in the context of the example.

"SurturZ" <su*****@newsgroup.nospamwrote in message
news:43**********************************@microsof t.com...
"Exit Try" instead of "Return" might be a bit easier to read, and allows
you
to have code after the Try block (eg. if the Try block is itself in an IF
block or somesuch).

--
David Streeter
Synchrotech Software
Sydney Australia
"Stephany Young" wrote:
>I think the point that has been missed is that you need to do some other
processing between the target of the 'goto' and the actual end of the
'sub'.

A mechanism that has been designed exactly for this purpose is the
Try...Finally...End Try construct.

In your case it would become something like:

sub method(byval param1 as integer, ...., BYREF result as String)

Try
.
result=callCOM1(params)
if result=-1 then
result="callCOM1 failed, dude!"
Return
End If
.
result=callCOM2(params)
if result=-1 then
result="callCOM2 failed, dude!"
Return
End If
.
Finally
'make some dispose, and additional tasks
End Try

end sub

Even though a 'return' theoretically returns immediately, the code in the
'Finally' block WILL be exected before the 'sub' actually returns.

That said, although I have no actual evidence to support it, my instinct
tells me that returning a value from a Function is probably more
efficient
than using a ByRef parameter. If it is not more efficient, then it is, in
my
opinion, more elegant and maintainable, both for the caller and callee.
They
way I would code it is:

Function method(byval param1 as integer, ....) As String

Try
Dim result as Integer
.
result=callCOM1(params)
if result=-1 then Return "callCOM1 failed, dude!"
.
result=callCOM2(params)
if result=-1 then Return "callCOM2 failed, dude!"
.
Return result.ToString()
Finally
'make some dispose, and additional tasks
End Try

End Function
"Roger Tranchez" <ru*****@community.nospamwrote in message
news:43**********************************@microso ft.com...
Hello,

Thanks for your answer.

I kew that about nested ifs, but I don't like it because it adds
complexity
to code.

I found the second method more elegant: do.. loop until true, I LIKE
it.
But, risking to be too fussy, this "loop until true" trick seems just a
bit
round-about 8-D

What do you think about the first question ? : to return if a procedure
has
done well its work you 'd use a FUNCTION that returns the result code
for
the operation, or a sub that, by means of a byref parameter returns the
result code ?

Wich is the paradigm for types of result codes: Strings, integers,
custom
objects ?

Thanks again,
Roger Tranchez
MCTS
.NET 2005 and DB developer
"AMercer" wrote:

The second doubt is the GOTO: you know, it is a bad wound in code,
but
I
use it as a fast way to exit the sub.
How would you change all this to be more structured and aesthetic ?

When I have some functions to perform in sequence and I want to quit
on
the
first failure, I use one of two constructs - 'nested if' or 'do once'.
I
prefer 'nested if' when I have few functions, I prefer 'do once' when
I
have
many.

Assuming the functions are x1, x2, and x3, 'nested if' is:

x1
If Success Then
x2
If Success Then
x3
If Success Then
' processing here for all success
End If
End If
End If

'Do Once':

Do
x1
If Fail Then Exit Do
x2
If Fail Then Exit Do
x3
If Fail Then Exit Do
' processing here for all success
Loop Until True

These constructs compile to code that is similar to yours with 'goto
endpoint', but the source code avoids goto's and label's. I prefer
them
over
goto's because I think they are easier to understand for a new person
or
for
you when you come back to the code after not looking at it for a few
months.

Jan 16 '08 #11

P: n/a
Now that's just getting picky for the sake of getting picky.

You had different expectations in a computer programmers' forum? :-)
As you can clearly see, there is NO code after the Try...Finally...End Try
block so your e. is completely irrelevant.
You are right, it is a style preference. I feel the Exit Try makes it more
obvious that the Finally block gets executed. But I suppose it is not too
much to ask that programmers know that a Finally block always gets executed.
Your code is certainly more compact and is a correct solution.
--
David Streeter
Synchrotech Software
Sydney Australia
"Stephany Young" wrote:
Now that's just getting picky for the sake of getting picky.

As you can clearly see, there is NO code after the Try...Finally...End Try
block so your e. is completely irrelevant.

In the context, changing the Return ... to Exit Try would add unecessary
complexity, because one would have to add Return ... after the End Try
which, in turn, would necessitate moving the declaration of _result to
before the Try.

As you can see, that is totally unecessary in the context of the example.

"SurturZ" <su*****@newsgroup.nospamwrote in message
news:43**********************************@microsof t.com...
"Exit Try" instead of "Return" might be a bit easier to read, and allows
you
to have code after the Try block (eg. if the Try block is itself in an IF
block or somesuch).

--
David Streeter
Synchrotech Software
Sydney Australia
"Stephany Young" wrote:
I think the point that has been missed is that you need to do some other
processing between the target of the 'goto' and the actual end of the
'sub'.

A mechanism that has been designed exactly for this purpose is the
Try...Finally...End Try construct.

In your case it would become something like:

sub method(byval param1 as integer, ...., BYREF result as String)

Try
.
result=callCOM1(params)
if result=-1 then
result="callCOM1 failed, dude!"
Return
End If
.
result=callCOM2(params)
if result=-1 then
result="callCOM2 failed, dude!"
Return
End If
.
Finally
'make some dispose, and additional tasks
End Try

end sub

Even though a 'return' theoretically returns immediately, the code in the
'Finally' block WILL be exected before the 'sub' actually returns.

That said, although I have no actual evidence to support it, my instinct
tells me that returning a value from a Function is probably more
efficient
than using a ByRef parameter. If it is not more efficient, then it is, in
my
opinion, more elegant and maintainable, both for the caller and callee.
They
way I would code it is:

Function method(byval param1 as integer, ....) As String

Try
Dim result as Integer
.
result=callCOM1(params)
if result=-1 then Return "callCOM1 failed, dude!"
.
result=callCOM2(params)
if result=-1 then Return "callCOM2 failed, dude!"
.
Return result.ToString()
Finally
'make some dispose, and additional tasks
End Try

End Function
"Roger Tranchez" <ru*****@community.nospamwrote in message
news:43**********************************@microsof t.com...
Hello,

Thanks for your answer.

I kew that about nested ifs, but I don't like it because it adds
complexity
to code.

I found the second method more elegant: do.. loop until true, I LIKE
it.
But, risking to be too fussy, this "loop until true" trick seems just a
bit
round-about 8-D

What do you think about the first question ? : to return if a procedure
has
done well its work you 'd use a FUNCTION that returns the result code
for
the operation, or a sub that, by means of a byref parameter returns the
result code ?

Wich is the paradigm for types of result codes: Strings, integers,
custom
objects ?

Thanks again,
Roger Tranchez
MCTS
.NET 2005 and DB developer
"AMercer" wrote:

The second doubt is the GOTO: you know, it is a bad wound in code,
but
I
use it as a fast way to exit the sub.
How would you change all this to be more structured and aesthetic ?

When I have some functions to perform in sequence and I want to quit
on
the
first failure, I use one of two constructs - 'nested if' or 'do once'.
I
prefer 'nested if' when I have few functions, I prefer 'do once' when
I
have
many.

Assuming the functions are x1, x2, and x3, 'nested if' is:

x1
If Success Then
x2
If Success Then
x3
If Success Then
' processing here for all success
End If
End If
End If

'Do Once':

Do
x1
If Fail Then Exit Do
x2
If Fail Then Exit Do
x3
If Fail Then Exit Do
' processing here for all success
Loop Until True

These constructs compile to code that is similar to yours with 'goto
endpoint', but the source code avoids goto's and label's. I prefer
them
over
goto's because I think they are easier to understand for a new person
or
for
you when you come back to the code after not looking at it for a few
months.

Jan 17 '08 #12

This discussion thread is closed

Replies have been disabled for this discussion.