Simple function with a goto
error handler:
void checkFile(char *name)
{
FILE *fp = fopen(name, "r");
if(NULL == fp)
{
fprintf(stderr, "Could not open %s\n", name);
goto end;
}
// use fp...
fclose(fp);
end:
;
}
Notice, if I remove the useless semicolon after end:
the function fails to compile.
On GCC:
error: expected primary-expression before '}' token
16 | }
On MSVC:
error C2143: syntax error: missing ';' before '}'
So, I understand that C standard does say that the destination of the goto
keyword expects a statement in § 6.8.6.1 p 2:
A goto statement causes an unconditional jump to the statement prefixed by the named label in the enclosing function
However, the error exists just because the label exists; if I remove the goto
keyword, the label itself is still treated as an error and won't compile. I read the standard's section on "Labeled statements" (§ 6.8.1) but still didn't find anything that explained this odd constraint.
In C a label may be placed before a statement. So if there is no statement you can place a null statement.
From the C Standard (6.8.1 Labeled statements)
labeled-statement:
identifier : statement
case constant-expression : statement
default : statement
And (6.8.3 Expression and null statements)
expression-statement:
expressionopt ;
3 A null statement (consisting of just a semicolon) performs no operations.
Opposite to C in C++ declarations are also statements. So in C++ you may place a label before a declaration.
Here are demonstrative programs.
C program.
#include <stdio.h>
int main(void)
{
goto End;
End:;
const char *bye = "Bye";
puts( bye );
return 0;
}
The program output is
Bye
C++ program
#include <iostream>
int main()
{
goto End;
End:
const char *bye = "Bye";
std::cout << bye << '\n';
return 0;
}
The program output is
Bye
Pay attention to that in the C program after the label there is placed a null statement
End:;
Without it the compiler will issue an error.