gpt4 book ai didi

c - 在 C 中初始化多个资源的函数中处理错误(清理和中止)的一些好方法是什么?

转载 作者:太空狗 更新时间:2023-10-29 16:01:16 25 4
gpt4 key购买 nike

首先,如果有人可以改写问题以使其更清楚,请这样做。

C 编程中的一个常见现象是有多个资源要按特定顺序初始化/分配。每个资源都是后续资源初始化的先决条件。如果其中一个步骤失败,则必须取消分配先前步骤中剩余的资源。理想的伪代码(利用神奇的通用 pure-unobtainium clean_up_and_abort() 函数)大致如下所示:

err=alloc_a()
if(err)
clean_up_and_abort()

err=alloc_b()
if(err)
clean_up_and_abort()

err=alloc_c()
if(err)
clean_up_and_abort()

// ...

profit()

我见过几种处理这个问题的方法,它们似乎都有明显的缺点,至少在人们倾向于认为的“良好做法”方面是这样。

在处理这种情况时,什么是最可读和最不容易出错的代码结构方式?效率是首选,但为了可读性,可以牺牲合理的效率。请列出优点和缺点。欢迎讨论多种方法的答案。

我们的目标是希望最终得到一组解决此问题的几种首选方法。

我将从我已经看到的一些方法开始,请对它们发表评论并添加其他方法

最佳答案

到目前为止我见过的三种最常见的方法:

1:嵌套 if 语句(SESE 纯粹主义者没有多次返回)。由于有一长串先决条件,这很快就会失控。 IMO,即使在简单的情况下,这也是可读性灾难并且没有真正的优势。我把它包括在内是因为我看到人们(太)经常这样做。

uint32_t init_function() {
uint32_t erra, errb, errc, status;
A *a;
B *b;
C *c;

erra = alloc_a(&a);
if(erra) {
status = INIT_FAIL_A;
} else {

errb = alloc_b(&b);
if(errb) {
dealloc_a(&a);
status = INIT_FAIL_B;
} else {

errc = alloc_c();
if(errc) {
dealloc_b(&b);
dealloc_a(&a);
status = INIT_FAIL_C;
} else {

profit(a,b,c);
status = INIT_SUCCESS;

}
}
}
// Single return.
return status;
}

2:多次返回。这是我目前首选的方法。逻辑很容易遵循,但它仍然很危险,因为清理代码必须重复,而且很容易忘记在清理部分之一中释放某些东西。

uint32_t init_function() {
uint32_t err;
A *a;
B *b;
C *c;

err = alloc_a(&a);
if(err) {
return INIT_FAIL_A;
}

err = alloc_b(&b);
if(err) {
dealloc_a(&a);
return INIT_FAIL_B;
}

err = alloc_c(&c);
if(err) {
dealloc_b(&b);
dealloc_a(&a);
return INIT_FAIL_C;
}

profit(a,b,c);
return INIT_SUCCESS;
}

3:转到。许多人原则上不喜欢 goto,但这是在 C 编程中有效使用 goto 的标准论据之一。优点是很难忘记清理步骤,并且没有复制粘贴。

uint32_t init_function() {
uint32_t status;
uint32_t err;
A *a;
B *b;
C *c;

err = alloc_a(&a);
if(err) {
status = INIT_FAIL_A;
goto LBL_FAIL_A;
}

err = alloc_b(&b);
if(err) {
status = INIT_FAIL_B;
goto LBL_FAIL_B;
}

err = alloc_c(&c);
if(err) {
status = INIT_FAIL_C;
goto LBL_FAIL_C;
}

profit(a,b,c);
status = INIT_SUCCESS;
goto LBL_SUCCESS;

LBL_FAIL_C:
dealloc_b(&b);

LBL_FAIL_B:
dealloc_a(&a);

LBL_FAIL_A:
LBL_SUCCESS:

return status;
}

还有什么我没有提到的吗?

关于c - 在 C 中初始化多个资源的函数中处理错误(清理和中止)的一些好方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32146616/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com