GNU C 扩展 __attribute__(__cleanup__) 是如何工作的?

How does GNU C extension __attribute__(__cleanup__) work?

它是否分析变量的生命周期并简单地在正确的位置插入清理函数调用?它有任何管理费用吗?

我写了两段简单的代码来比较性能,并在没有优化的情况下编译了它们。

代码 1:

#include <stdio.h>
#include <stdlib.h>

void clean_up(int **final_value)
{
    free(*final_value);
}

int main(int argc, char **argv)
{
  for (int i = 0; i < 10000000; i++) { 
    int *avar = malloc(sizeof(int));
    clean_up(&avar);
  }

  return 0;
}

代码 2:

#include <stdio.h>
#include <stdlib.h>

void clean_up(int **final_value)
{
    free(*final_value);
}

int main(int argc, char **argv)
{
  for (int i = 0; i < 10000000; i++) { 
    int *avar __attribute__ ((__cleanup__(clean_up))) = malloc(sizeof(int));
  }

  return 0;
}

而且他们的表现也很相似

当变量超出范围时调用清除函数。它不在乎,这是否会使其他指针悬空。

你最好通过一些优化进行编译,特别是如果你想查看生成的汇编代码(使用 gcc -S -fverbose-asm -O 编译)

直觉 behind __attribute__((cleanup)) 是 GCC 实际上是所有 C、C++、Ada、Fortran、Go 的编译器....该属性强制使用与相同的内部表示对于局部变量的 C++ 析构函数。清理发生在当前块范围的末尾(例如,在块的右大括号 } 处)。因此,编译器正在将带有清理功能的 code2 转换为 code1 的等价物。

全局变量或静态变量的析构函数(在 main 返回后 运行)在函数上 __attribute__((destructor))(在 运行 =18=] 插件时间)。

因此,要理解这些属性,您最好用 C++ 术语来思考。

我的观点是,如果您需要这些 cleanup 属性,您应该使用 C++ 而不是 C 来编写代码。您的代码将更具可读性并且更少依赖编译器。我觉得 cleanup 实际上只在生成的 C 代码中有用。没用过(感觉需要用的时候应该转C++)