为什么在函数末尾放置标签时必须包含分号?
Why must I include a semicolon when putting a label at the end of a function?
带有 goto
错误处理程序的简单函数:
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:
;
}
注意,如果我在 end:
之后删除无用的分号,函数将无法编译。
在 GCC 上:
error: expected primary-expression before '}' token
16 | }
在 MSVC 上:
error C2143: syntax error: missing ';' before '}'
所以,我知道 C 标准确实说 goto
关键字的目标需要 § 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
但是,仅仅因为标签存在,错误就存在;如果我删除 goto
关键字,标签本身仍被视为错误并且不会编译。我阅读了标准中关于“标记语句”的部分(§ 6.8.1),但仍然没有找到任何可以解释这种奇怪约束的内容。
在 C 中,标签可以放在语句之前。因此,如果没有语句,您可以放置一个空语句。
来自 C 标准(6.8.1 标记语句)
labeled-statement:
identifier : statement
case constant-expression : statement
default : statement
和(6.8.3 表达式和空语句)
expression-statement:
expressionopt ;
3 A null statement (consisting of just a semicolon) performs no
operations.
在C++声明中与C相对的也是语句。所以在 C++ 中,你可以在声明之前放置一个标签。
这里有演示程序。
C程序.
#include <stdio.h>
int main(void)
{
goto End;
End:;
const char *bye = "Bye";
puts( bye );
return 0;
}
程序输出为
Bye
C++程序
#include <iostream>
int main()
{
goto End;
End:
const char *bye = "Bye";
std::cout << bye << '\n';
return 0;
}
程序输出为
Bye
注意C程序中在label后面放了一个null语句
End:;
没有它编译器会报错。
带有 goto
错误处理程序的简单函数:
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:
;
}
注意,如果我在 end:
之后删除无用的分号,函数将无法编译。
在 GCC 上:
error: expected primary-expression before '}' token
16 | }
在 MSVC 上:
error C2143: syntax error: missing ';' before '}'
所以,我知道 C 标准确实说 goto
关键字的目标需要 § 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
但是,仅仅因为标签存在,错误就存在;如果我删除 goto
关键字,标签本身仍被视为错误并且不会编译。我阅读了标准中关于“标记语句”的部分(§ 6.8.1),但仍然没有找到任何可以解释这种奇怪约束的内容。
在 C 中,标签可以放在语句之前。因此,如果没有语句,您可以放置一个空语句。
来自 C 标准(6.8.1 标记语句)
labeled-statement:
identifier : statement
case constant-expression : statement
default : statement
和(6.8.3 表达式和空语句)
expression-statement:
expressionopt ;
3 A null statement (consisting of just a semicolon) performs no operations.
在C++声明中与C相对的也是语句。所以在 C++ 中,你可以在声明之前放置一个标签。
这里有演示程序。
C程序.
#include <stdio.h>
int main(void)
{
goto End;
End:;
const char *bye = "Bye";
puts( bye );
return 0;
}
程序输出为
Bye
C++程序
#include <iostream>
int main()
{
goto End;
End:
const char *bye = "Bye";
std::cout << bye << '\n';
return 0;
}
程序输出为
Bye
注意C程序中在label后面放了一个null语句
End:;
没有它编译器会报错。