Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c

gcc

pragma

I just discovered the #pragma weak directive in GCC:

6.57.9 Weak Pragmas

For compatibility with SVR4, GCC supports a set of #pragma directives for declaring symbols to be weak, and defining weak aliases.

#pragma weak symbol

This pragma declares symbol to be weak, as if the declaration had the attribute of the same name. 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. It is an error if symbol2 is not defined in the current translation unit.

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:

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. 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.

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.

So with all the preliminaries finished, my actual questions are: Am I mistaken about #pragma weak having this "portability" advantage? and Do all modern compilers on unix-like systems (gcc, pcc, tinycc, icc, llvm/clang, etc.) still support the traditional 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

like image 321
R.. GitHub STOP HELPING ICE Avatar asked Feb 24 '12 02:02

R.. GitHub STOP HELPING ICE


1 Answers

Neither "#pragma weak" nor __attribute__ is part of the C standard, so neither is, strictly speaking, portable. Some C compilers strive to be compatible with most of GCC's extensions to the C standard, others do not.

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__.

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. 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. #pragma is harder to use in that manner. Such a macro can also conceal the difference between various name manglings by using the CPP pasting operator ("##" etc.)

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

like image 161
Perry Avatar answered Sep 18 '22 18:09

Perry