简体   繁体   English

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

[英]How widely supported is pragma weak, and does it overcome the issues of using gcc attribute?

I just discovered the #pragma weak directive in GCC: 我刚刚在GCC中发现了#pragma weak指令:

6.57.9 Weak Pragmas 6.57.9弱的语用

For compatibility with SVR4, GCC supports a set of #pragma directives for declaring symbols to be weak, and defining weak aliases. 为了与SVR4兼容,GCC支持一组#pragma指令,用于声明符号弱,并定义弱别名。

#pragma weak symbol

This pragma declares symbol to be weak, as if the declaration had the attribute of the same name. 该pragma声明符号为弱,就好像声明具有相同名称的属性一样。 The pragma may appear before or after the declaration of symbol. 该编译指示可能出现在符号声明之前或之后。 It is not an error for symbol to never be defined at all. 符号永远不会被定义,这不是错误。

#pragma weak symbol1 = symbol2

This pragma declares symbol1 to be a weak alias of symbol2. 该pragma将symbol1声明为symbol2的弱别名。 It is an error if symbol2 is not defined in the current translation unit. 如果未在当前转换单元中定义symbol2,则会出错。

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

Despite the fact that the GCC developers generally don't like #pragma and encourage you to use __attribute__ instead for all sorts of things that could be pragmas, I'm inclined to believe #pragma weak may actually be superior to the attribute-based approach, which looks like: 尽管GCC开发人员通常不喜欢#pragma并鼓励你使用__attribute__代替可能是pragma的各种事情,但我倾向于认为#pragma weak可能实际上优于基于属性的方法,看起来像:

extern __typeof(old_name) new_name __attribute__(weak, alias("old_name"))

Aside from the ugliness of requiring __typeof (or requiring you to know the type and spell it out explicitly, even if it's a really complex function type), the biggest issue of the attribute based approach is that "old_name" must be passed to gcc as a string to be pasted literally into the generated assembly. 除了要求__typeof的丑陋(或者要求你明确知道类型并拼写它,即使它是一个非常复杂的函数类型),基于属性的方法的最大问题是必须将"old_name"传递给gcc as要将字符串粘贴到生成的程序集中的字符串 This is problematic because different systems have different name-mangling characteristics (most popular is prefixing an underscore on all C symbol names, or doing nothing at all), and to pass the correct string to the alias attribute, you need to know the name mangling convention of the system you're building for, which is really not knowledge that belongs in an application-level library where weak aliases might be useful. 这是有问题的,因为不同的系统具有不同的名称修改特性(最流行的是在所有C符号名称前加下划线,或根本不执行任何操作),并且要将正确的字符串传递给alias属性,您需要知道名称mangling您正在构建的系统的约定,这实际上不是属于弱别名可能有用的应用程序级库的知识。

The syntax #pragma weak new_name = old_name seems to avoid this issue by handling both names at the compiler level, where t can mangle them both appropriately, unless I'm mistaken. 语法#pragma weak new_name = old_name似乎通过在编译器级别处理这两个名称来避免这个问题,其中t可以适当地处理它们,除非我弄错了。

So with all the preliminaries finished, my actual questions are: Am I mistaken about #pragma weak having this "portability" advantage? 所有的预赛都完成后,我的实际问题是: 我错误地认为#pragma weak有这种“便携性”的优势吗? and Do all modern compilers on unix-like systems (gcc, pcc, tinycc, icc, llvm/clang, etc.) still support the traditional SVR4 #pragma weak ? 并且所有类似unix的系统上的现代编译器(gcc,pcc,tinycc,icc,llvm / clang等)仍然支持传统的SVR4 #pragma weak

I'm aware of the following similar question, but it does not seem quite the same and the answers to not satisfactorily address my question: 我知道以下类似的问题,但它似乎并不完全相同,答案不能令人满意地解决我的问题:

How portable is weak linking? 弱连接的便携性如何? #pragma weak my_symbol #pragma weak my_symbol

Neither "#pragma weak" nor __attribute__ is part of the C standard, so neither is, strictly speaking, portable. “#pragma weak”和__attribute__都不是C标准的一部分,因此严格来说,它们都不是可移植的。 Some C compilers strive to be compatible with most of GCC's extensions to the C standard, others do not. 一些C编译器努力与大多数GCC对C标准的扩展兼容,而其他C编译器则没有。

Generally speaking, if you're already at the level of talking about weak symbols and weak aliases, you probably are past the point where you can write code that is reliably portable across compilers. 一般来说,如果你已经处于讨论弱符号和弱别名的水平,那么你可能已经超出了编写可以在编译器中可靠移植的代码的程度。 Even your toolchain will become an issue here (including especially the linker) -- I don't think you can rely on anything without carefully testing. 甚至你的工具链也会成为一个问题(尤其是链接器) - 我认为如果不仔细测试你就不能依赖任何东西。

Edited to add: The original poster commented below asking whether, pragmatically, #pragma is no less portable than __attribute__. 编辑添加:原始海报评论如下,问实际上,#pragma是否比__attribute__便携。

My own experience has been this: it is nice to be able to hide all such things inside of macros or other generated code in order to make portability easier. 我自己的经验是这样的:能够在宏或其他生成的代码中隐藏所有这些东西以便使可移植性更容易是很好的。 __attribute__ is easier to conceal inside a portability header file. __attribute__更容易隐藏在可移植性头文件中。 For example, at least one of the BSD kernels has a cdefs.h that uses __attribute__ inside a macro to centralize the way that weak definitions are done throughout the code base to allow easier changes to new compilers. 例如,至少有一个BSD内核有一个cdefs.h,它在宏中使用__attribute__来集中在整个代码库中完成弱定义的方式,以便更容易地更改新的编译器。 #pragma is harder to use in that manner. #pragma以这种方式使用起来比较困难。 Such a macro can also conceal the difference between various name manglings by using the CPP pasting operator ("##" etc.) 这样的宏也可以通过使用CPP粘贴操作符(“##”等)来隐藏各种名称修改之间的差异。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM