【发布时间】:2011-02-18 18:48:09
【问题描述】:
在调试崩溃时,我在一些代码中遇到了这个问题:
int func()
{
char *p1 = malloc(...);
if (p1 == NULL)
goto err_exit;
char *p2 = malloc(...);
if (p2 == NULL)
goto err_exit;
...
err_exit:
free(p2);
free(p1);
return -1;
}
当第一个 malloc 失败时会出现问题。因为我们跳过了p2的初始化,它包含随机数据并且对free(p2)的调用可能会崩溃。
我希望/希望这将被视为与 C++ 中相同的方式,其中编译器不允许 goto 跳过初始化。
我的问题:是跳过标准允许的初始化还是 gcc 的 c99 实现中的错误?
【问题讨论】:
-
看到一些程序如何通过跳过初始化来知道它们在做什么,我打赌“它是允许的”,但这是我时区延长周末的前一天晚上,所以我不是在查。不过问题很好。
-
有趣 - 就我一眼看得出,C99 标准对 goto 过去的声明/初始化保持沉默,只是它说您不能从外部跳转到具有 VLA 的范围范围。再说一次,我可能没有在所有正确的地方寻找......
-
这是一个很好的例子,说明了为什么 goto “被认为是有害的”。我并不完全反对它,但它可以让这样的事情变得容易但不那么明显。
-
@nategoose:不幸的是,这种错误处理是 goto 具有合法用途的领域之一(无论如何我认为)。太糟糕了,即使这样使用它仍然很容易出错
-
@Michael Burr:我也很抱歉。我不认为你的评论是负面的,我也不打算给自己留下负面的印象。由于很多人(理论上)从这里发布的内容中学习,我不希望有人知道
goto本质上是好是坏,甚至是进行错误处理或不进行错误处理的方式。有时它是最好用的东西,有时是最坏的东西,有时它是最好的但用得非常糟糕。