带有一个 goto 标签的 C 代码未按预期工作

Posted

技术标签:

【中文标题】带有一个 goto 标签的 C 代码未按预期工作【英文标题】:C code with one goto label not working as expected 【发布时间】:2012-10-19 18:30:06 【问题描述】:

有人要求我分解一个 C 程序,该程序最初只是一个主要方法,其中包含许多注释良好的段。如果发生错误,每个段都使用相同的定义函数字符串“die”。 die 函数使用 goto 标签 'out' 来关闭程序。

在将这些段中的每一个都转换为现在都从底部缩小的 main 方法调用的函数之后,每个段的 goto out 代码不再起作用。 “out”标签在 main 中,XCode 编译器告诉我 goto 标签尚未定义。

所以我想我在问如何以最有效的方式在每个本地函数中定义我的输出标签?

这里有一些代码 sn-ps,全部按照它们出现的顺序/结构:

模具定义

    #define die(msg, ...) do                       \
(void) fprintf (stderr, msg, ## __VA_ARGS__); \
(void) fprintf (stderr, "\n");                \
goto out;                                     \
 while (0)

使用 die 的函数示例

void createContext(void)
        context = clCreateContext (0, 1, &device_id, NULL, NULL, &err);
        if (!context || err != CL_SUCCESS)
            die ("Error: Failed to create a compute context!");
    

最后是我的 main,其中包含最后来自 die 的 out 标签

main (int argc, char *argv[])


    (Several functions called here)

out:
    /* Shutdown and cleanup.  */
    if (data)
        free (data);

    if (results)
        free (results);

    return rc;

【问题讨论】:

goto 标签仅适用于单个函数,其中一个函数中有 goto 而另一个函数中的标签未定义 你会想要让所有新函数返回错误代码,在 main() 中检查它并只转到那里。 longjmp/setjmp 是一个全局 goto,但我认为这里不是一个好主意。 即使在这里使用goto 是不好的风格,问题本身是好的。我认为没有理由投反对票。 @H2CO3 @H2CO3,遗留代码是有时使用 goto 的充分理由。问题不在于 goto 是否是一个好主意。 有人听说过最新的编程新闻吗? Goto considered harmful。哇,这是一些激进的观点,让我们开始辩论! 【参考方案1】:

goto 不能跨越函数。如果您使用goto,它必须是与goto 相同功能内的标签。

要在函数之间进行跳转,请查看 setjmplongjmp 函数。

但是,在您的情况下,由于您只是跳转退出程序,因此您可以直接调用exit。所有资源(打开的文件、分配的内存)都将由运行时库和操作系统释放。

【讨论】:

而且这个exit仍然允许我使用die的错误信息? @Chucky 当然,只要把它放在goto 的位置上,printf 调用就会照常执行。

以上是关于带有一个 goto 标签的 C 代码未按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

带有分页的可扩展嵌套 Angular 材料数据表未按预期工作?

Lerna 发布工作流程未按预期发布

IOS 8 高度约束动画未按预期工作

C 基本代码未按预期工作

带有可选子命令的 argparse 未按预期工作

播放 HTML5 音频标签,但控件未按预期工作