gcc 预编译器指令 __attribute__ ((__cleanup__)) vs ((cleanup)) (带 vs 不带下划线?)

Posted

技术标签:

【中文标题】gcc 预编译器指令 __attribute__ ((__cleanup__)) vs ((cleanup)) (带 vs 不带下划线?)【英文标题】:gcc precompiler directive __attribute__ ((__cleanup__)) vs ((cleanup)) (with vs without underscores?) 【发布时间】:2015-09-25 15:08:17 【问题描述】:

我正在学习 gcc 的 cleanup attribute,并学习当变量超出范围时它如何调用要运行的函数,我不明白为什么您可以使用带或不带下划线的“清理”一词. 带有下划线的版本的文档或文档在哪里?

上面的 gcc 文档是这样显示的:

__attribute__ ((cleanup(cleanup_function)))

但是,我阅读的大多数代码示例都是这样显示的:

__attribute__ ((__cleanup__(cleanup_function)))

例如:

http://echorand.me/site/notes/articles/c_cleanup/cleanup_attribute_c.html http://www.nongnu.org/avr-libc/user-manual/atomic_8h_source.html

请注意,第一个示例链接表明它们是相同的,当然编码证明了这一点,但他最初是怎么知道的呢?这是哪里来的?

为什么不一样? __cleanup__ 在哪里定义或记录,而不是 cleanup

我的根本问题在于我不知道我不知道什么,因此我试图暴露我的一些未知的未知数,以便它们成为已知的未知数,直到我可以研究它们并使它们为人所知。

我的想法是,gcc 预处理器指令可能有一些全球适用的原则,您可以在其中任意添加下划线之前或之后? ——或者也许只是其中的一部分? -- 或者它以某种方式修改了预处理器指令或属性,并且在某些情况下,一种方法(带或不带额外下划线)优于另一种方法?

【问题讨论】:

您提供的第一个链接暗示(如果不是直接声明)cleanup__cleanup__ 是相同的。此外,鉴于您已将其标记为 C++,我还将提到它的最佳目的似乎是在 C 样式代码中使用 RAII 语义。一般来说,在 C++ 中,您应该将需要清理的东西包装到具有析构函数的类中(并暗示 - 通过 c++11 或更高版本的三规则或五规则 - 您还需要构造函数和/ 或移动运算符)。 谢谢。我进一步阐述了我的问题。第一个链接确实说明它们是相同的,但我想知道这对我使用的其他属性意味着什么……是否总是有多个相同的选项?这家伙怎么知道他们是一样的?当然,这种差异肯定存在某种原因。请参阅我的更新答案,了解我的一些疑惑。 【参考方案1】:

您可以定义宏cleanup,因为它不是为编译器保留的名称。您不能定义一个名为__cleanup__ 的名称。这保证了您使用 __cleanup__ 的代码不受其他代码的影响(当然,前提是其他代码的行为)。

【讨论】:

【参考方案2】:

正如https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html#Attribute-Syntax 解释的那样:

您可以选择在名称前后使用__ 指定属性名称。这允许您在头文件中使用它们,而不必担心可能的同名宏。例如,您可以使用属性名称__noreturn__ 而不是noreturn

(但请注意,属性不是预处理器指令。)

【讨论】:

谢谢。如果不是预处理器指令,那么属性是什么?预处理器指令是如何定义的?另外,是否有术语“编译器指令”?这有什么不同? 预处理器指令类似于#include#define#ifdef 那你怎么称呼__attribute__?如果不是“指令”,那么这类事情的好词是什么? 这是一个(非标准扩展)关键字

以上是关于gcc 预编译器指令 __attribute__ ((__cleanup__)) vs ((cleanup)) (带 vs 不带下划线?)的主要内容,如果未能解决你的问题,请参考以下文章

Linux gcc支持的语法 __attribute__ 属性设置

__attribute__((packed))作用

利用gcc的__attribute__编译属性section子项构建初始化函数表

gcc编译,出现错误:expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ........

ubuntukylin基础 使用gcc编译一个C语言 helloworld程序 预编译 汇编 编译 链接

C/C++常用预编译指令介绍