【问题标题】:Why must I include a semicolon when putting a label at the end of a function?为什么在函数末尾添加标签时必须包含分号?
【发布时间】:2021-03-02 21:14:53
【问题描述】:

带有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 节),但仍然没有找到任何可以解释这种奇怪约束的内容。

【问题讨论】:

  • 所以它需要一个声明。 ; 是一个空语句。没有它就没有声明。
  • end: {} 也是一个语句,不需要分号:-)
  • Re “所以,我知道 C 标准确实说 goto 关键字的目标需要一个语句”:那么你的问题是什么?既然您知道 goto 指向以标签为前缀的语句,那么您为什么对标签必须有语句感到惊讶?
  • 呃。让我猜猜:您有一些限制性的代码标准,阻止您在失败后立即执行return,而必须使用goto。编写这个短视要求的人完全无法理解您为什么首先要编写代码标准:使代码始终更具可读性。强制使用 goto 使该测试失败。这就像奥运跳水运动员在比赛中做炮弹一样。

标签: c label goto


【解决方案1】:

在 C 语言中,标签可以放在语句之前。因此,如果没有语句,您可以放置​​一个空语句。

来自 C 标准(6.8.1 标记语句)

labeled-statement:
    identifier : statement
    case constant-expression : statement
    default : statement

And(6.8.3 表达式和空语句)

expression-statement:
    expressionopt ;

3 空语句(仅由分号组成)执行 no 操作。

与 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程序中标签后面有一个空语句

End:;

没有它编译器会报错。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 2022-10-24
    • 1970-01-01
    • 2019-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多