goto 的合法使用

问题描述

为了使用 goto 语句,我在更汇编风格的循环中重写了 while 循环:

// while
int i=0;
while (i++<10)
    printf("%d...",i);
// asm-ish
loop:
    i++;
    printf("%d...",i);
    if (i<10)
        goto loop;
loop_exit:
    return 0;

除了某种学术练习之外,是否有任何实际/有用的示例说明如何使用 goto 语句?或者这基本上是未使用的 c 的残余部分。

以下是一个广泛使用它的代码文件示例:https://github.com/postgres/postgres/blob/ca3b37487be333a1d241dab1bbdd17a211a88f43/src/port/snprintf.c

我想我能想到的一件事是在不必使用一堆 continue/break 的情况下摆脱深层嵌套,但仅此而已。

解决方法

虽然您可以以这种方式使用 goto,但它通常被认为是不好的风格,因为该语言具有其他结构,例如 while,它们在“清洁器”中执行相同的操作时尚。

曾经使用 goto 的地方是为了错误处理情况而向前跳。例如,这个:

void foo()
{
    char *p1 = NULL,*p2 = NULL,*p3 = NULL,*p4 = NULL;
    
    p1 = malloc(1000);
    if (!p1) {
        perror("malloc failed");
        return;
    }
    p2 = malloc(1000);
    if (!p2) {
        perror("malloc failed");
        free(p1);
        return;
    }
    p3 = malloc(1000);
    if (!p3) {
        perror("malloc failed");
        free(p2);
        free(p1);
        return;
    }
    p4 = malloc(1000);
    if (!p4) {
        perror("malloc failed");
        free(p3);
        free(p2);
        free(p1);
        return;
    }

    // Do something with p1,p2,p3,p4

    free(p4);
    free(p3);
    free(p2);
    free(p1);
}

可以翻译成这样:

void foo()
{
    char *p1 = NULL,*p4 = NULL;
    
    p1 = malloc(1000);
    if (!p1) {
        perror("malloc failed");
        goto err0;
    }
    p2 = malloc(1000);
    if (!p2) {
        perror("malloc failed");
        goto err1;
    }
    p3 = malloc(1000);
    if (!p3) {
        perror("malloc failed");
        goto err2;
    }
    p4 = malloc(1000);
    if (!p4) {
        perror("malloc failed");
        goto err3;
    }

    // Do something with p1,p4

    free(p4);
err3:
    free(p3);
err2:
    free(p2);
err1:
    free(p1);
err0:
    return;
}

这会将所有清理代码放在一个地方。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...