c - 为什么在函数末尾添加标签时必须包含分号?
问题描述
带有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 中声明:
goto 语句导致无条件跳转到以封闭函数中的命名标签为前缀的语句
但是,错误的存在只是因为标签存在;如果我删除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 空语句(仅由分号组成)不执行任何操作。
在 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后面有一个空语句
End:;
没有它,编译器将发出错误。
推荐阅读
- java - 为什么在某些情况下我们必须将 Immutable 转换为 Pair?
- node.js - 在 MongoDB 中存储 Amazon SNS 的令牌
- python - 如何使用此时间序列数据进行作物预测?
- javascript - addEventListener("change" ... 用于改变 innerHTML 的输入工程的值上升但不下降
- powerbi - 如何设置 Power BI 许可证
- javascript - 访问复杂 javascript 对象的元素
- python - 是否有更有效的方法来迭代矩阵并在特定列上执行计算?
- html - 向下滚动时,如何使它与我的视频重叠?
- sql - 为什么在 Postgres 中查询 LTREE 时字符串连接不起作用?
- grails - grails 4 sessionRegistry为空