Effect of goto on local variables

P

pertheli

I am in a situation where only "goto" seems to be the answer for my
program logic where I have to retry calling some repeated functions.

Can anybody help in the usage of goto and its effect in local
variables, as shown in the stripped code below


void MyClass:process(){

int iMaxRetry = 100;
int iRetryCount = 0;
.....
.....
Retry:
iRetryCount++; // counter for retrying
somefunction1();
bool bNewBool = FALSE; // some local variable
char* myVar1 = malloc(100);
CSomeClass myVar2;
if (!somefunction2()){ // if condition is not valid retry
if (iRetryCount < iMaxRetry){
if (myVar1) free(myVar1);
goto Retry; // go back and try again
}
}

.....
.....
}

What is the effect of calling repeated "Retry:" block to the local
variables such as bNewBool, myVar1, myVar2? Are they called again? ie
reinitialised? Is it safe to use? although it seems to be working fine
 
N

Nils Petter Vaskinn

I am in a situation where only "goto" seems to be the answer for my
program logic where I have to retry calling some repeated functions.


bool bNewBool;
char* myVar1;
CSomeClass myVar2;

while (true);
iRetryCount++; // counter for retrying
somefunction1();
bNewBool = FALSE; // some local variable
myVar1 = malloc(100);

if (!somefunction2()){ // if condition is not valid retry
if (iRetryCount < iMaxRetry){
if (myVar1) free(myVar1);
goto Retry; // go back and try again
} else {
break;
}
}
}

.....
.....
}
 
N

Nils Petter Vaskinn

bool bNewBool;
char* myVar1;
CSomeClass myVar2;

while (true);

agh replace the ';' with '{' obviously
iRetryCount++; // counter for retrying
somefunction1();
bNewBool = FALSE; // some local variable
myVar1 = malloc(100);

if (!somefunction2()){ // if condition is not valid retry
if (iRetryCount < iMaxRetry){
if (myVar1) free(myVar1);
goto Retry; // go back and try again

The goto should ofcourse have been removed too
} else {
break;
}
}
}

....
....
}

Need to proofread before I post
 
A

Alf P. Steinbach

I am in a situation where only "goto" seems to be the answer for my
program logic

Don't use "goto".

where I have to retry calling some repeated function

Use a loop.

That's what loops are for.


Can anybody help in the usage of goto

Yes. Avoid "goto".


and its effect in local variables

Generally the effect of a "goto" is that you fail to understand
what's going on.


as shown in the stripped code below


void MyClass:process(){

int iMaxRetry = 100;

Do you really want to have that limit as a variable instead of constant?


int iRetryCount = 0;
....
....
Retry:
iRetryCount++; // counter for retrying

Don't use postincrement.

Don't use comment instead of code.

Don't use Hungarian notation.


somefunction1();
bool bNewBool = FALSE; // some local variable

In C++ 'FALSE' is spelled 'false', that is, lowercase.


char* myVar1 = malloc(100);

Don't use malloc.

CSomeClass myVar2;

This doesn't seem to be used anywhere.

if (!somefunction2()){ // if condition is not valid retry
if (iRetryCount < iMaxRetry){
if (myVar1) free(myVar1);

Isn't that a little late to check whether the allocation succeeded?


goto Retry; // go back and try again

Don't use 'goto'.

}
}

....
....
}



void MyClass:process()
{
int const maxRetries = 100;
.....
.....

for( int retryCount = 0; retryCount < maxRetries; ++retryCount )
{
somefunction1();
if( somefunction2() )
{
break;
}
}

.....
.....
}

What is the effect of calling repeated "Retry:" block to the local
variables such as bNewBool, myVar1, myVar2? Are they called again? ie
reinitialised? Is it safe to use? although it seems to be working fine

You really don't need to know. Just avoid "goto".
 
M

Mike Smith

pertheli said:
I am in a situation where only "goto" seems to be the answer for my
program logic where I have to retry calling some repeated functions.

void MyClass:process(){

int iMaxRetry = 100;
int iRetryCount = 0;
....
....
replace

Retry:

with

bool retry;
do {
retry = false;
iRetryCount++; // counter for retrying
somefunction1();
bool bNewBool = FALSE; // some local variable
char* myVar1 = malloc(100);
CSomeClass myVar2;
if (!somefunction2()){ // if condition is not valid retry
if (iRetryCount < iMaxRetry){
if (myVar1) free(myVar1);
replace

goto Retry; // go back and try again

with

retry = true;

} while (retry);
 
E

Erik

bool bNewBool;
char* myVar1;
CSomeClass myVar2;

while (true);
iRetryCount++; // counter for retrying
somefunction1();
bNewBool = FALSE; // some local variable
myVar1 = malloc(100);

if (!somefunction2()){ // if condition is not valid retry
if (iRetryCount < iMaxRetry){
if (myVar1) free(myVar1);
goto Retry; // go back and try again
} else {
break;
}
}
}

In what respect is this code more easy to read the the OP's?
 
A

Ashok Viswanathan

pertheli said:
I am in a situation where only "goto" seems to be the answer for my
program logic where I have to retry calling some repeated functions.

Can anybody help in the usage of goto and its effect in local
variables, as shown in the stripped code below


void MyClass:process(){

int iMaxRetry = 100;
int iRetryCount = 0;
....
....
Retry:
iRetryCount++; // counter for retrying
somefunction1();
bool bNewBool = FALSE; // some local variable
char* myVar1 = malloc(100);
CSomeClass myVar2;
if (!somefunction2()){ // if condition is not valid retry
if (iRetryCount < iMaxRetry){
if (myVar1) free(myVar1);
goto Retry; // go back and try again
}
}

....
....
}

What is the effect of calling repeated "Retry:" block to the local
variables such as bNewBool, myVar1, myVar2? Are they called again? ie
reinitialised? Is it safe to use? although it seems to be working fine

If you dump the assembly, one will get an idea of what the compiler does
with gotos.

Local Variables would be stored in the stack. So the compiler would emit
instructions which will load values of the variables from the stack to
temporary registers for further computation of the variables in the body of
the procedure.

When you have a goto, the compiler simply emits a branch to that location in
the procedure which in this case will simply load the values from the stack
again to where it used to continue computation. But before it does the
branch, it would have stored the current contents of the registers back on
the stack. They can then be reload from the stack to some other register if
required later in the program. What will be used beyond the goto stmt is the
current value of the variable in the stack and older values will be
over-written. Just try it and check.
 
N

Nils Petter Vaskinn

In what respect is this code more easy to read the the OP's?

The "while" makes it obvious that we're looping. label+goto is (IMNSHO)
less obvious. The generally accepted wisdom is to not use goto unless you
have to, this is clearly a case of "doesn't have to"
 

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,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top