清理模式 [英] Cleanup patterns

查看:105
本文介绍了清理模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好


我只是想知道大多数人如何在C函数中实现清理。

特别是,如果函数打开了许多资源,这些需要

如果在

函数中的任何一点发生错误(以及成功时的结尾)都会正确发布。 C ++有例外,

我能在C中看到这样做的唯一方法就是使用goto

语句。我实施清理的方法是否合适,或者是他们更好的方式。这是一个例子,它使用全局错误来存储

错误。


#define CLEANUP(错误)({errno =(err); goto清理})


int example_function()

{

SOMETYPE * a,b,c;

errno = 0;


if(!(a = malloc(sizeof(a))))

CLEANUP(ENOMEM);


if(!(b = malloc(sizeof(b))))

CLEANUP(ENOMEM);


if(b !(c = malloc(sizeof(c))))

CLEANUP(ENOMEM);


/ *在这里做点什么* /


清理:

如果(a)

免费(a);

如果(b);

免费(b);

如果(c)

免费(c);

if(errno)

返回-1;

返回0;

}

Hi all

I am just wondering how most people implement cleanup in C functions.
In particular, if the function opens a number of resources, these need
to be released properly should an error occur at any point in the
function (as well as at the end if successful). C++ has exceptions,
the only way I can see to do this neatly in C is to use goto
statements. Is my method of implementing cleanup good, or are their
better ways. Here is an example, which uses the global errno to store
the error.

#define CLEANUP(err) ({errno = (err); goto cleanup})

int example_function()
{
SOMETYPE * a,b,c;
errno = 0;

if(!(a = malloc(sizeof(a))))
CLEANUP(ENOMEM);

if(!(b = malloc(sizeof(b))))
CLEANUP(ENOMEM);

if(!(c = malloc(sizeof(c))))
CLEANUP(ENOMEM);

/* do something here */

cleanup:
if(a)
free(a);
if(b);
free(b);
if(c)
free(c);
if(errno)
return -1;
return 0;
}

推荐答案



MQ写道:

MQ wrote:

大家好


我只是想知道如何大多数人在C函数中实现清理。

特别是,如果函数打开了许多资源,如果在

函数中的任何一点发生错误(以及成功时的结尾),这些都需要

正确发布。 C ++有例外,

我能在C中看到这样做的唯一方法就是使用goto

语句。我实施清理的方法是否合适,或者是他们更好的方式。这是一个例子,它使用全局错误来存储

错误。


#define CLEANUP(错误)({errno =(err); goto清理})
Hi all

I am just wondering how most people implement cleanup in C functions.
In particular, if the function opens a number of resources, these need
to be released properly should an error occur at any point in the
function (as well as at the end if successful). C++ has exceptions,
the only way I can see to do this neatly in C is to use goto
statements. Is my method of implementing cleanup good, or are their
better ways. Here is an example, which uses the global errno to store
the error.

#define CLEANUP(err) ({errno = (err); goto cleanup})



不要使用带跳跃的宏而不是。

Don''t use macros with jumps and what not.


int example_function( )

{

SOMETYPE * a,b,c;
int example_function()
{
SOMETYPE * a,b,c;



b和c不是指针[或者至少与指针不在同一水平]

b and c are not pointers [or at least not at the same level as a]


errno = 0;


if(!(a = malloc(sizeof(a))))

CLEANUP(ENOMEM);

if(!(b = malloc(sizeof(b))))

CLEANUP(ENOMEM);


if(!(c = malloc(sizeof(c))))

CLEANUP(ENOMEM);
errno = 0;

if(!(a = malloc(sizeof(a))))
CLEANUP(ENOMEM);

if(!(b = malloc(sizeof(b))))
CLEANUP(ENOMEM);

if(!(c = malloc(sizeof(c))))
CLEANUP(ENOMEM);



我会做的只是


a = malloc(sizeof(* a));

if(a == NULL){errno = outofmem;转到ERR_A; }

b = ...

if(b == NULL){errno = outofmem;转到ERR_B; }

....


然后在最后有


errno = 0;


ERR_C:

免费(b);

ERR_B:

免费(一);

ERR_A:

返回errno;

}


使代码易于理解并且不涉及讨厌如果'到处都是

这个地方(例如,如果你避免全部聚在一起..)


Tom

I''d do simply

a = malloc(sizeof(*a));
if (a == NULL) { errno = outofmem; goto ERR_A; }
b = ...
if (b == NULL) { errno = outofmem; goto ERR_B; }
....

Then at the end have

errno = 0;

ERR_C:
free(b);
ERR_B:
free(a);
ERR_A:
return errno;
}

Makes the code easy to follow and doesn''t involve nasty if''s all over
the place (e.g. if you avoided goto all together..)

Tom


MQ写道:
MQ wrote:

大家好


我只是想知道大多数人是怎么回事在C函数中实现清理。

特别是,如果函数打开了许多资源,如果在<中的任何一点发生错误,这些都需要正确释放

br />
函数(如果成功则在最后)。 C ++有例外,

我能在C中看到这样做的唯一方法就是使用goto

语句。
Hi all

I am just wondering how most people implement cleanup in C functions.
In particular, if the function opens a number of resources, these need
to be released properly should an error occur at any point in the
function (as well as at the end if successful). C++ has exceptions,
the only way I can see to do this neatly in C is to use goto
statements.



在C中,通常使用嵌套if',和/或仔细

初始化变量,和/或分解成多个

函数,和/或转到。

In C, it''s typical to use nested if''s, and/or carefully
initialized variables, and/or decomposition into multiple
functions, and/or goto.


我的实现清理的方法是好的,还是他们的

更好的方法。这是一个例子,它使用全局errno存储

错误。
Is my method of implementing cleanup good, or are their
better ways. Here is an example, which uses the global errno to store
the error.



您的方法是Bad(tm)。对于初学者来说,它不会编译。

这可以通过更改宏定义来修复,但是然后

你将调用未定义的行为,如果其中一个前两个

malloc()调用失败。此外,标准C没有定义ENOMEM,

和'errno!= 0''不是有效的失败测试。


所有这些问题很容易修复或解决,但

考虑:你已经提升了CLEANUP,实质上是一种帮助

编写更好的程序的方法。既然它确实有*不帮助

你写一个更好的程序,也许是时候质疑它的b / b
效果了,不是吗?

Your method is Bad(tm). For starters, it won''t compile.
That could be fixed by changing the macro definition, but then
you''d be invoking undefined behavior if either of the first two
malloc() calls failed. Also, Standard C doesn''t define ENOMEM,
and `errno!=0'' is not a valid test for failure.

All of these problems are easily fixed or worked around, but
consider: You''ve advanced CLEANUP as, essentially, a way to help
write better programs. Since it demonstrably has *not* helped
you to write a better program, perhaps it''s time to question its
effectiveness, no?


#define CLEANUP(错误)({errno =(err); goto cleanup})


int example_function()

{

SOMETYPE * a,b,c;

errno = 0;


if(!(a = malloc) (sizeof(a))))

CLEANUP(ENOMEM);


if(!(b = malloc(sizeof(b))))

CLEANUP(ENOMEM);


if(!(c = malloc(sizeof(c))))

CLEANUP(ENOMEM) ;


/ *在这里做点什么* /


清理:

如果(a)

免费(一);

如果(b);

免费(b);

if(c)

免费(c);

if(错误号)

返回-1;

返回0;

}
#define CLEANUP(err) ({errno = (err); goto cleanup})

int example_function()
{
SOMETYPE * a,b,c;
errno = 0;

if(!(a = malloc(sizeof(a))))
CLEANUP(ENOMEM);

if(!(b = malloc(sizeof(b))))
CLEANUP(ENOMEM);

if(!(c = malloc(sizeof(c))))
CLEANUP(ENOMEM);

/* do something here */

cleanup:
if(a)
free(a);
if(b);
free(b);
if(c)
free(c);
if(errno)
return -1;
return 0;
}



-

Eric Sosman
es ***** @ acm-dot-org.inva 盖子

--
Eric Sosman
es*****@acm-dot-org.invalid




Eric Sosman写道:

Eric Sosman wrote:

MQ写道:
MQ wrote:

大家好


我只是想知道大多数人如何在C函数中实现清理。

特别是,如果函数打开了许多资源,这些需要

到如果在

函数中的任何一点发生错误(以及如果成功的话,最后都会发生错误)。 C ++有例外,

我能在C中看到这样做的唯一方法就是使用goto

语句。
Hi all

I am just wondering how most people implement cleanup in C functions.
In particular, if the function opens a number of resources, these need
to be released properly should an error occur at any point in the
function (as well as at the end if successful). C++ has exceptions,
the only way I can see to do this neatly in C is to use goto
statements.



在C中,通常使用嵌套if',和/或仔细

初始化变量,和/或分解成多个

函数,和/或转到。


In C, it''s typical to use nested if''s, and/or carefully
initialized variables, and/or decomposition into multiple
functions, and/or goto.


我的实现清理的方法是好的,还是他们的

更好的方法。这是一个例子,它使用全局errno存储

错误。
Is my method of implementing cleanup good, or are their
better ways. Here is an example, which uses the global errno to store
the error.



您的方法是Bad(tm)。对于初学者来说,它不会编译。

这可以通过更改宏定义来修复,但是然后

你将调用未定义的行为,如果其中一个前两个

malloc()调用失败。此外,标准C没有定义ENOMEM,

和'errno!= 0''不是有效的失败测试。


Your method is Bad(tm). For starters, it won''t compile.
That could be fixed by changing the macro definition, but then
you''d be invoking undefined behavior if either of the first two
malloc() calls failed. Also, Standard C doesn''t define ENOMEM,
and `errno!=0'' is not a valid test for failure.



嗨Eric


我确实把这个放在一起很快,毫无疑问会有一个

错误的数量,但发布后我修复了这些问题,它确实编译好了。忽略这一点,我只想知道代码的一般

结构是不是很好的做法。你应该能够确定我想要实现的目标......

MQ。

Hi Eric

I did throw this together rather quickly and no doubt there will be a
number of errors, but after posting I fixed these problems and it does
compile fine. Ignoring this, I just want to know if the general
structure of the code is good practise. You should be able to
ascertain what I am trying to achieve...
MQ.


这篇关于清理模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆