Reputation: 847
I am writing some C code and in my code I have two nested loops. On a particular condition I want to break
out of the inner loop and continue
the outer loop. I tried to achieve this using a label at the end on the outer loop's code and, on the condition, goto
that label. However gcc
gives an error that I cannot have a label at the end of a compound statement. Why not?
Note 1: This is not a switch
statement and that question has been answered elsewhere.
Note 2: This is not a question about style and whether I should or should not be using goto
statements or conditional variables instead.
EDIT: People have asked for an example and I can give a slightly facile example of checking if an array is a subarray of another array
int superArray[SUPER_SIZE] = {...}, subArray[SUB_SIZE] = {...};
int superIndex, subIndex;
for (superIndex=0; superIndex<SUPER_SIZE-SUB_SIZE; superIndex+=1)
{
for (subIndex=0; subIndex<SUB_SIZE; subIndex+=1)
if (superArray[superIndex+subIndex] != subArray[subIndex])
goto break_then_continue;
// code that executes if subArray is a sub array
break_then_continue:
}
Upvotes: 36
Views: 19705
Reputation: 63797
In the standard it's explicitly said that labels belong to a statement, therefore a simple semicolon (;
) after your label can circumvent the problem you are running in to, since that counts as a statement.
There is even an example of the use of an "empty"1 statement in 6.8.3/6.
EXAMPLE 3 A null statement may also be used to carry a label just before the closing } of a compound statement
while (loop1) {
/* ... */
while (loop2) {
/* ... */
if (want_out)
goto end_loop1;
/* ... */
}
/* ... */
end_loop1: ;
}
1 In the standard this is referred to as a null statement
.
6.8.1 Labeled statements
Syntax 1 labeled-statement: identifier : statement case constant-expression : statement default : statement
Notice that statement
isn't optional in the above quotation.
Upvotes: 50
Reputation: 145829
The label should point to a statement.
C mandates this:
(C99, 6.8.1 Labeled statements p4) " Any statement may be preceded by a prefix that declares an identifier as a label name."
In your case you can use a null statement:
void foo(void)
{
goto bla;
bla:
;
}
Null statements perform no operation.
Or you can also use a compound statement (a block) if you have declarations:
void foo(void)
{
goto bla;
bla:
{
int x = 42;
printf("%d\n", x);
}
}
Upvotes: 6
Reputation: 753695
You simply need to write:
label: ;
The semi-colon is an empty statement. You need it because the language is defined like that; you need to go to a statement, even if it is an empty one.
for (int i = 0; i < N; i++)
{
for (int j = 0; i < M; j++)
{
...
if (some_condition)
goto continue_loop1;
...
}
continue_loop1: ;
}
You can argue about the indentation on the label.
Upvotes: 6