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

gcc precompiler directive __attribute__ ((__cleanup__)) vs ((cleanup)) (with vs without underscores?)

我正在学习 gcc 的 cleanup attribute,并了解当变量超出范围时它如何调用一个函数 运行,我不明白为什么你可以使用带或不带下划线的单词 "cleanup"。 下划线的版本的文档或文档在哪里?

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

__attribute__ ((cleanup(cleanup_function)))

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

__attribute__ ((__cleanup__(cleanup_function)))

例如:

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

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

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

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

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

You may optionally specify attribute names with __ preceding and following the name. This allows you to use them in header files without being concerned about a possible macro of the same name. For example, you may use the attribute name __noreturn__ instead of noreturn.

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

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