Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C/C++: goto into the for loop

I have a bit unusual situation - I want to use goto statement to jump into the loop, not to jump out from it.

There are strong reasons to do so - this code must be part of some function which makes some calculations after the first call, returns with request for new data and needs one more call to continue. Function pointers (obvious solution) can't be used because we need interoperability with code which does not support function pointers.

I want to know whether code below is safe, i.e. it will be correctly compiled by all standard-compliant C/C++ compilers (we need both C and C++).

function foo(int not_a_first_call, int *data_to_request, ...other parameters... )
{
    if( not_a_first_call )
        goto request_handler;
    for(i=0; i<n; i++)
    {
        *data_to_request = i;
        return;
request_handler:
        ...process data...
    }
}

I've studied standards, but there isn't much information about such use case. I also wonder whether replacing for by equivalent while will be beneficial from the portability point of view.

Thanks in advance.

UPD: Thanks to all who've commented!

  1. to all commenters :) yes, I understand that I can't jump over initializers of local variables and that I have to save/restore i on each call.

  2. about strong reasons :) This code must implement reverse communication interface. Reverse communication is a coding pattern which tries to avoid using function pointers. Sometimes it have to be used because of legacy code which expects that you will use it.

Unfortunately, r-comm-interface can't be implemented in a nice way. You can't use function pointers and you can't easily split work into several functions.

like image 418
Sergey Avatar asked May 16 '11 18:05

Sergey


People also ask

Can we use goto statement in for loop?

The goto statement can be used to alter the flow of control in a program. Although the goto statement can be used to create loops with finite repetition times, use of other loop structures such as for, while, and do while is recommended.

Is goto a loop in C?

Goto is a jump statement that can alter the normal flow of execution of code. Using the goto statement, you can not only jump to a part of the code below the current flow but also a part above the current flow. This also enables goto statements to initiate loops in the program, without using for or while in the code.

Why goto is avoided in C?

NOTE − Use of goto statement is highly discouraged in any programming language because it makes difficult to trace the control flow of a program, making the program hard to understand and hard to modify.

What is goto statement in C?

The goto statement allows us to transfer control of the program to the specified label .


1 Answers

Seems perfectly legal.

From a draft of the C99 standard http://std.dkuug.dk/JTC1/SC22/WG14/www/docs/n843.htm in the section on the goto statement:

[#3] EXAMPLE 1 It is sometimes convenient to jump  into  the
   middle  of  a  complicated set of statements.  The following
   outline presents one possible approach to a problem based on
   these three assumptions:

     1.  The  general initialization code accesses objects only
         visible to the current function.

     2.  The  general  initialization  code  is  too  large  to
         warrant duplication.

     3.  The  code  to  determine  the next operation is at the
         head of the loop.  (To  allow  it  to  be  reached  by
         continue statements, for example.)

           /* ... */
           goto first_time;
           for (;;) {
                   // determine next operation
                   /* ... */
                   if (need to reinitialize) {
                           // reinitialize-only code
                           /* ... */
                   first_time:
                           // general initialization code
                           /* ... */
                           continue;
                   }
                   // handle other operations
                   /* ... */
           }

Next, we look at the for loop statement:

[#1]  Except for the behavior of a continue statement in the |
   loop body, the statement

           for ( clause-1 ; expr-2 ; expr-3 ) statement

   and the sequence of statements

           {
                   clause-1 ;
                   while ( expr-2 ) {
                           statement
                           expr-3 ;
                   }
           }

Putting the two together with your problem tells you that you are jumping past

i=0;

into the middle of a while loop. You will execute

...process data...

and then

i++;

before flow of control jumps to the test in the while/for loop

i<n;
like image 161
Jose_X Avatar answered Sep 17 '22 15:09

Jose_X