Read someone's code today to see a "#pragma weak", for a moment did not understand, on the Internet to study an afternoon finally slightly understand a little C, C + + "weak symbol", the following is my understanding, not the correct place to hope that you correct.
This article mainly from the following three aspects of the "weak symbol":
1. What is a "weak symbol"? What is the difference between it and the strong symbol?
2. What is the role of weak symbols?
3. Practical application examples of weak symbols
1. What are weak symbols?
In Wikipedia, the definition of weak symbols is:
A weak symbol is a symbol definition in an object file or dynamic library, which is overridden by the other symbol Definitio Ns
a weak symbol denotes A specially annotated symbol during linking of executable and Linkable Format (ELF) object files.
By default, without any annotation, the a symbol in an object file is strong.
During linking, a strong symbol can override a weak symbol of the same name.
In contrast, and strong symbols that share a name yield a link error during link-time.
When linking a binary executable, a weakly declared symbol does not need a definition.
in comparison, [by default] a declared strong symbol without a definition triggers an undefined symbol link error. Weak symbols is not mentioned by C or C + + language standards; As such, inserting them into code are not very portable.
Even if platforms support the same or similar syntax for marking symbols as weak,
The semantics may differ in Subtle points, e.g. whether weak symbols during dynamic linking at runtime lose their semantics or not
From the first definition, it is known that the "weak symbol" is a symbol that is defined in a file or in a dynamic library and can be overridden by symbols defined elsewhere. The point here is "overridden."
From the second definition, we can know that the "weak symbol" and strong symbols are mainly the following differences:
1. Weak symbols can only be declared, not defined, strong symbols must have a definition
2. Weak symbols can be defined more than once, and strong symbols are defined only.
The second definition also mentions that weak symbols are not content in the C and C + + specifications, which are related to the compiler and are not portable.
In many articles in Chinese, weak symbol is divided into two "weak symbols" (variables) "weakly quoted" (functions), but the examples of weak symbols in Wikipedia are the functions used.
2. The role of weak symbols
My understanding of "weak symbolic variables" is a legacy of C, which has no effect in addition to causing trouble. In C language, all global variables that are not initialized are weak symbolic variables, and if there are multiple weak symbolic variables with the same name, the compiler can choose any one at the link (some compiler chooses the one that occupies the most space). In this way, you define an x in your code, forget the initialization, and you use a library that just defines an uninitialized x, and you can think of it as a consequence. This problem does not occur in C + + because all uninitialized global variables in C + + are initialized to 0.
The main function of weak symbolic functions is to polymorphism, that is, using the definition of "overridden", generally used in the library is more, such as you in your library for a function to provide a default implementation, users want to customize the words can be implemented by themselves.
Example: what function foo is a weak symbolic function in Library_foo.h, LIBRARY_FOO.CC provides a default implementation for Foo, and a custom implementation for Foo in my_foo.cc.
Note: There are two ways of defining a function as a weak function
1. Use "#pragma week function"
2. Add "__attribute__ ((weak))" After the function,
The GCC I'm using doesn't seem to support the first way.
// library_foo.h #ifndef __library_foo_h__ #define __library_foo_h__void FOO () __attribute__ ((weak)); void f (); #endif
// library_foo.cc #include <iostream> #include library_foo.h " void Foo () {std::cout <<" default foo <<STD::ENDL;} void F () {foo ();}
// main.cc <iostream> #include " library_foo.h " using namespace Std; int Main (int argc, char * argv[]) {f ();}
// my_foo.cc <iostream>void foo () { std::cout<<"My customized foo "<<Std::endl;}
The results of compiling and running are as follows:
> g++ library_foo. cc Main. cc My_foo. cc -o customized.x> g++ library_foo. cc Main. cc -o not_customized.x>./customized.xmy customized foo>./not_ Customized.xdefault Foo
As you can see, when the link my_foo.cc is, the custom foo is used.
3. Practical application examples of weak symbols
In the C + + library, the following functions are weak symbolic functions
void*operator New(std::size_t);void*operator New(std::size_t, std::nothrow_tConst&) noexcept;void*operator New[] (std::size_t);void*operator New[] (std::size_t,Conststd::nothrow_t&) noexcept;void operator Delete(void*) noexcept;void operator Delete(void*, std::nothrow_tConst&) noexcept;void operator Delete[](void*) noexcept;void operator Delete[](void*, std::nothrow_tConst&) Noexcept;
The meaning and example of weak sign (weak reference) in C + +