便携式等同于gcc的__attribute __(清理)

ezp*_*zpz 15 c portability gcc garbage-collection scope

最近我遇到了一个gcc扩展,我发现它非常有用: __attribute__(cleanup)

基本上,这允许您在退出范围时为局部变量分配清理调用.例如,给定以下代码部分,必须在调用期间的任何和所有情况下显式维护和处理所有内存foo.

void foo() {
   char * buff = ...; /* some memory allocation */
   char * buff2 = 0, * buff3 = 0;
   if (! buff) {
      return;
   } else {
      buff2 = ...; /* memory allocation */
      if (! buff2) {
         goto clean_exit;
      } else {
         /* ... and so on ... */
      }
   }

clean_exit:
   free (buff);
   free (buff2);
   free (buff3);
}
Run Code Online (Sandbox Code Playgroud)

但是,通过使用可以减少到的扩展名

#define clean_pchar_scope __attribute__((cleanup(pchar_free)))

void pchar_free (char ** c) { free (*c); }

void foo () {
   char * buff clean_pchar_scope = ...; /* some memory allocation */
   char * buff2 clean_pchar_scope = 0, * buff3 clean_pchar_scope = 0;
   if (! buff)
      return;
   buff2 = ...; /* memory allocation */
   if (! buff2)
      return;
   /* and so on */
}
Run Code Online (Sandbox Code Playgroud)

现在,所有内存都在范围的基础上回收,而不使用嵌套的if/else或goto构造以及函数的统一内存释放部分.我意识到goto的使用可以避免使用更多嵌套的if/else结构(所以,请不要对goto进行神圣的战争......)并且这个例子是设计的,但事实仍然是这可能是非常有用的功能.

不幸的是,据我所知,这是特定于gcc的.我对任何便携式方法感兴趣(如果它们存在的话).有没有人有过使用gcc之外的其他方面的经验?

编辑: 似乎可移植性没有发挥作用.考虑到这一点,有没有办法在gcc空间之外做到这一点?似乎很好的功能是gcc特定的......

dpi*_*dpi 9

__attribute__(cleanup)不是特定于 gcc 的,clang 和 icc 也支持它,这使得 msvc 成为唯一不支持它的主要编译器(无论如何,这个编译器对于现代 C 开发来说毫无用处)。

因此,即使它不在 ISO 标准中,对于大多数实际用途来说,它也可以被认为是便携式的。


Dan*_*son 8

在C中没有可移植的方式.

幸运的是,这是带有析构函数的C++的标准功能.

编辑:

MSVC似乎有__try和__finally关键字,也可以用于此目的.这与C++异常处理不同,我认为它在C中可用.

我认为你会发现清理和try/finally并没有被广泛使用,因为C++中的隐式支持,它与C"足够接近",对行为感兴趣的人可以轻松地将代码转换为C++.


R..*_*R.. 5

问题的前半部分是可移植的方法。