如何广泛支持pragma weak,它是否克服了使用gcc属性的问题?

R..*_*R.. 6 c gcc pragma

我刚刚#pragma weak在GCC中发现了该指令:

6.57.9弱的语用

为了与SVR4兼容,GCC支持一组#pragma指令,用于声明符号弱,并定义弱别名.

#pragma weak symbol

该pragma声明符号为弱,就好像声明具有相同名称的属性一样.该编译指示可能出现在符号声明之前或之后.符号永远不会被定义,这不是错误.

#pragma weak symbol1 = symbol2

该pragma将symbol1声明为symbol2的弱别名.如果未在当前转换单元中定义symbol2,则会出错.

http://gcc.gnu.org/onlinedocs/gcc/Weak-Pragmas.html

尽管GCC开发人员通常不喜欢#pragma并鼓励您使用__attribute__可能是pragma的各种事物,但我倾向于认为#pragma weak可能实际上优于基于属性的方法,它看起来像:

extern __typeof(old_name) new_name __attribute__(weak, alias("old_name"))
Run Code Online (Sandbox Code Playgroud)

除了要求的丑陋__typeof(或要求你知道的类型和拼写出来明确,即使这是一个非常复杂的函数类型),属性为基础的方法最大的问题是,"old_name"必须通过与gcc 作为一个字符串是从字面上粘贴到生成的程序集中.这是有问题的,因为不同的系统具有不同的名称修改特性(最流行的是在所有C符号名称前加下划线,或根本不执行任何操作),并且要将正确的字符串传递给alias属性,您需要知道名称修改约定您正在构建的系统,这实际上不是属于应用程序级库的知识,其中弱别名可能有用.

语法#pragma weak new_name = old_name似乎通过在编译器级别处理这两个名称来避免这个问题,其中t可以适当地修改它们,除非我弄错了.

所有的预赛都完成后,我的实际问题是:我是否错误地认为#pragma weak这具有"便携性"优势?并且所有类似unix的系统上的现代编译器(gcc,pcc,tinycc,icc,llvm/clang等)是否仍然支持传统的SVR4 #pragma weak

我知道以下类似的问题,但它似乎并不完全相同,答案不能令人满意地解决我的问题:

弱连接的便携性如何?#pragma weak my_symbol

Per*_*rry 5

“#pragmaweak”和 __attribute__ 都不是 C 标准的一部分,因此严格来说,两者都不是可移植的。一些 C 编译器努力与大多数 GCC 对 C 标准的扩展兼容,而其他编译器则不然。

一般来说,如果您已经达到了讨论弱符号和弱别名的水平,那么您可能已经过了可以编写跨编译器可靠移植的代码的阶段。即使你的工具链也会成为一个问题(尤其是链接器)——我认为如果没有仔细测试,你就不能依赖任何东西。

编辑添加:原发帖者在下面评论询问,从实用角度来看,#pragma 的可移植性是否不低于 __attribute__。

我自己的经验是这样的:能够将所有这些东西隐藏在宏或其他生成的代码中以使可移植性更容易,这是很好的。__attribute__ 更容易隐藏在可移植性头文件中。例如,至少有一个 BSD 内核有一个 cdefs.h,它在宏内使用 __attribute__ 来集中整个代码库中弱定义的完成方式,以便更轻松地更改新编译器。#pragma 更难以这种方式使用。这样的宏还可以通过使用 CPP 粘贴运算符(“##”等)来隐藏各种名称修饰之间的差异。

有关此类用法的示例,请参阅: http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/sys/cdefs.h ?rev=1.89.6.1&content-type=text/x-cvsweb-markup