c99 转到过去的初始化

标签 c gcc c99 goto

在调试崩溃时,我在一些代码中遇到了这个问题:

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 实现中的错误?

最佳答案

当您使用 -Wjump-misses-init 跳过变量定义时,您可以要求 gcc 发出警告,然后您可以使用 -Werror (或者,更多准确地说,-Werror=jump-misses-init)来强制用户处理它。此警告包含在 -Wc++-compat 中因此 gcc 开发人员知道代码在 C 和 C++ 中的行为有所不同。

您还可以稍微更改代码:

int func()
{
    char *p1 = malloc(...);
    if (p1 == NULL)
        goto err_exit_1;

    char *p2 = malloc(...);
    if (p2 == NULL)
        goto err_exit_2;

    ...

err_exit_2:
    free(p2);
err_exit_1:
    free(p1);

    return -1;
}

...并继续将标签与初始化变量配对。使用统一变量调用许多其他函数时,您也会遇到同样的问题,free 只是一个更明显的问题。

关于c99 转到过去的初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40379107/

相关文章:

c - 查找特定序列的所有素数

c - 在 C 中,编译时计算什么?

c - 没有 "inline"或 "static"的 "extern"在 C99 中有用吗?

c++ - 如何加载知道第一个元素的结构?

c - 在打包/解包结构之间切换

c - 如何在内核模式驱动程序中使用 Winsock 内核 (WSK) 发送原始套接字数据包?

c - 同步不同的消息

c++ - 如何在 Linux 上部署 C++ 应用程序

iphone - LLVM 2.0 无法为 iPhone 模拟器构建。 GCC 4.2 工作正常

python - libpython2.7.a 缺少许多引用