在这段代码中使用goto有什么好处?

Jee*_*tel 4 c error-handling goto gstreamer

static gboolean
gst_fd_src_start (GstBaseSrc * bsrc)
{
  GstFdSrc *src = GST_FD_SRC (bsrc);

  src->curoffset = 0;

  if ((src->fdset = gst_poll_new (TRUE)) == NULL)
    goto socket_pair;

  gst_fd_src_update_fd (src, -1);

  return TRUE;

  /* ERRORS */
socket_pair:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ_WRITE, (NULL),
        GST_ERROR_SYSTEM);
    return FALSE;
  }
}
Run Code Online (Sandbox Code Playgroud)

为什么这里有人使用 goto socket_pair;我不知道为什么使用这种机制?为什么我们不在那里写错误信息并返回?

注意:这是gstreamer插件代码

Dav*_*nan 11

在较大的例程中,函数中可能存在多个需要goto错误处理代码的点.应该在根据代码约定编写的上下文中看到此例程,该代码约定要求使用常见的错误处理形式.

确实goto应该被认为是危险的,但对于像C这样没有异常处理的语言,它可能是错误处理的最不好的选择.


T.J*_*der 7

在您引用的代码中,基本上没有任何充分的理由.

但是,一般情况下,如果函数需要在失败时执行多项操作(例如,不仅仅返回错误代码),或者如果编码标准,您有时会在函数的底部看到"错误处理"标签每个功能需要一个单独 return的功能(一些政府工作会这样做).然后主体代码用于goto在需要时触发错误处理.这有点像穷人的try/catch/finally事.

例如:

int someNiftyFunction() {
    int rv = 0;

    acquireSomeResource();

    if (some_failure_condition) {
        rv = -1;
        goto error_out;
    }

    if (some_other_failure_condition) {
        rv = -2;
        goto error_out;
    }

    if (yet)_another_failure_condition) {
        rv = -3;
        goto error_out;
    }

    setUpSuccessStuff();

exit:
    cleanUpSomeResource();
    return rv;

error_out:

    setUpFailureStuff();
    logSomeValuableInfo();
    goto exit;
}
Run Code Online (Sandbox Code Playgroud)

在那里,基本上从标签acquireSomeResource()exit:标签的所有内容都非常粗略try,exit:标签是finally,并且error_out是捕获.非常粗略.:-)


And*_*ndy 5

如果这是旧式的C,它没有作为语言结构内置的异常处理,这个习惯用法是模拟它的好方法.

想象有10个早期退出条件.如果你想将每个代码编码为return语句,你必须重复调用GST_ELEMENT_ERROR 10次,而使用goto意味着你只需要把它放一次.

很明显,在这种情况下,只有一个早期退出条件,但通常更好的方法是通过代码实现这个习惯用法,而不仅仅是在严格需要它的函数中