First of all, I said it was a tragedy, before I saw the programmer's ego-link, load and library. C has strong symbols, weak symbols, strong references, and weak references. When I saw the 3.5.5 Weak signs and strong symbols, I feel a little confused, so write this article, I hope to be able to communicate with the same feeling of friends also hope that the expert advice.
First, let's take a look at the book's definition of them.
Introduces the scenario: (1) in file A, the variable i (int i = 1) is defined and initialized, and the variable i (int i = 2) is defined in file B. Compile link A, b error B.O: (. data+0x0): Multiple definition of ' I '; A.O: (. data+0x0): Multiple definition of ' I '. (2) Define and initialize two variables i (int i = 1; int i = 2) in file C, and the error c.c:2:5:error:redefinition of ' I ' when compiling the link; c.c:1:5:note:previous definition of ' I ' is here.
Strong symbol: A symbolic definition like this in a scene is called a strong symbol, and for C + +, the compiler default function and the initialized global variable are strong symbols.
Weak symbol: Next, the initialized global variable is a weak symbol.
The compiler's rules for strong and weak symbols are: (1) The strong symbol does not allow multiple definitions, but it can coexist, (2) strong coverage is weak, (3) are weak symbols, choose the most occupied space, such as choosing double type instead of int type.
By the above definition so there are scenes I didn't think of before:
Code A.C:
1 int i = 2;
Code B.C:
Copy Code code as follows:
#include <stdio.h>
int i;
int main (int argc, char** argv)
{
printf ("i =%d\n", i);
return 0;
}
Compile files A and B and link, the result output I is 2 instead of 0.
And the two identical variables that are defined in the same file but not initialized are not an error and will only be error when using variables.
For the GCC compiler, it is also permissible to use __attribute__ ((weak)) to define a strong symbol as a weak symbol,
Code C.C
Copy Code code as follows:
#include <stdio.h>
__ATTRIBUTE__ ((weak)) int i = 1;
int main (int argc, char** argv)
{
printf ("i =%d\n", i);
return 0;
}
The output of result I is still not 2, not 1.
So is this true for functions as well? Instead of looking at the function, we first look at the strong and weak references that are further introduced by strong and weak symbols. An overview of strong and weak references in the book is that it is definitely an error if the link is not defined. For weak references, there is no error, the linker defaults to 0 (this is a good understanding of the function, that is, the function symbol represents the entry address of 0; For variables to be aware of, since it is a reference to the nature is the address, So a variable with the same function as the address of 0 instead of a variable value of 0). Is there no clear concept for strong or weak references at this time? What exactly is a reference? What is the relationship between references and symbols? Here let me say what I understand (welcome to correct), the function name and variable name specified at the definition and declaration are the corresponding symbols, and when calling functions or using variables elsewhere in the code, the function description and variable names are considered references, so that symbols and references are actually a thing at the code level, It's just different from the environment. Then the strong symbol refers to the Chingqiang, and the weak symbol corresponds to the weak reference.
There is a strong and weak reference to the characteristics of the above, when a function is a weak reference, regardless of the function is not defined, the link will not be an error, and we can determine whether the function name is 0来 to decide whether to execute this function. As a result, libraries containing these functions can be combined with modules, plug-ins, and our references for ease of use and unloading, and because strong symbols can cover weak symbols and the relationship between strength and weakness, we can define our own functions to cover functions in the library, how wonderful.
First look at the criteria to determine whether to perform functions:
Code D.C
Copy Code code as follows:
#include <stdio.h>
void Func ()
{
printf ("func () #1 \ n");
}
Code E.C
Copy Code code as follows:
#include <stdio.h>
__ATTRIBUTE__ ((weak)) void Func ();
int main (int argc, char** argv)
{
if (func)
Func ();
return 0;
}
Compile d.c,cc-c D.C output D.O, compile e.c and link d.o,cc d.o e output executable file E, run e normal execution function e.c-o. Compiles e.c but does not link D.O, this time does not have the error, only Func does not execute, because does not have its definition so if (func) is false.
Then look at the function overlay:
Code F.C
Copy Code code as follows:
#include <stdio.h>
__ATTRIBUTE__ ((weak)) void Func ()
{
printf ("func () #1 \ n");
}
Code G.C
Copy Code code as follows:
#include <stdio.h>
void Func ()
{
printf ("func () #2 \ n");
}
int main (int argc, char** argv)
{
Func ();
return 0;
}
~
Compile link, structure output "func () #2".
The above can show that the function and variable are consistent, in fact, the strain can also be used as a function to determine the use of the first, but not the value of the variable, but the address of the variable, such as
Code V1.C
Copy Code code as follows:
Code V2.C
Copy Code code as follows:
#include <stdio.h>
__ATTRIBUTE__ ((weak)) extern int i;
int main (int argc, char** argv)
{
if (&i)
printf ("i =%d\n", i);
return 0;
}
~
When compiling and linking v1, the output is 2, and no output occurs when the V1 is compiled but not linked. To do this, distinguish between definition and declaration, __attribute__ ((weak) int i is to define a variable and convert it to a weak symbol, so I is allocating space, and __attribute__ (weak) extern int I Converts the previously defined variable i from a strong symbol to a weak symbol, resulting in the use of I not as a strong reference but as a weak reference. But although variables can do this, there is no function that makes sense.
The above is still using gcc-provided __attribute__ (weak), and the book also mentions __attribute__ (Weakref), which appears to be more of a "quote" keyword. The reason why I use the former to introduce strong and weak quotes is because of my understanding of the corresponding relationship between strong and weak symbols and strong and weak references. With regard to the use of __attribute__ (WEAKREF), here is a description (both of which have different usage methods).
Code A.C
Copy Code code as follows:
#include <stdio.h>
void Bar ()
{
printf ("foo () \ n");
}
Code B.C
Copy Code code as follows:
#include <stdio.h>
static void Foo () __attribute__ ((Weakref ("Bar"));
int main (int argc, char** argv)
{
if (foo)
Foo ();
return 0;
}
Note that the static modifier of the function foo is not an error, so that the function foo is restricted to use only in this file.
Well, the night has been deep, write a bit messy, I also messy.