On C language in the strong symbol weak symbol strong reference and weak reference

  • 2020-04-02 02:54:05
  • OfStack

First of all, I'm sad that I didn't know C had strong symbols, weak symbols, strong references, and weak references until I read programmer's self-cultivation: linking, loading, and libraries. When I saw the weak symbol and strong symbol in section 3.5.5, I felt a little confused, so I wrote this article, hoping to communicate with friends with the same feeling and also hope that the superior person can give advice.

First let's look at the definition of them in the book.

Introduction scenario :(1) the variable I (int I = 1) is defined and initialized in file A, and the variable I (int I = 2) is defined and initialized in file B. 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), an error will be reported when compiling the link. Note: previous definition of 'I' was here.

Strong notation: a notation definition like the one in the scenario is called strong notation, and for C/C++, the compiler's default functions and initialized global variables are strong notation.
Weak sign: the global variable initialized is a weak sign.
Compiler rules about strong and weak symbols are :(1) strong symbols are not allowed to be defined more than once, but strong and weak symbols can coexist; (2) when weak and strong coexist, strong covers weak; (3) when both are weak symbols, choose the one with the largest space, such as double instead of int.

As defined above, there are scenarios that I didn't think of before:
A.c code:

1 int I = 2;
Biggest code:


#include<stdio.h> int i;
int main(int argc, char** argv)
{
      printf("i = %dn", i);
      return 0;     
}

Compile files a and b and link, resulting in output I of 2 instead of 0.
And two identical variables defined in the same file but not initialized will not report an error, only when using variables will report an error.
For the GCC compiler, it is also allowed to use arbitration ((weak)) to define a strong symbol as a weak symbol, which already exists
Code Arthur c.


 #include<stdio.h>
 
  __attribute__((weak)) int i = 1;
 
  int main(int argc, char** argv)
  {
       printf("i = %dn", i);
       return 0;  
  }

The output of result I is still not 2 but 1.

Is that true for functions? Let's not look at the function, but at the strong and weak references that are further introduced by the strong and weak symbols. The overview of strong and weak references in the book is that if the strong reference is not defined, the link will definitely report an error, but if the weak reference is not defined, the link will default to 0. For variables to be aware of, since the reference is natural is the address, so like the function the address of the variable is 0 instead of the value of the variable is 0). Isn't there a clear concept of strong or weak references? What exactly is a quote? What is the relationship between a reference and a symbol? Here I said I understand (correct) welcome, in defining the harmony as the function name, variable name shall specify the corresponding symbols, and in other code calls the function or use variables, is the letter of instructions and the variable name as a reference, so that symbols and reference in the code level is a thing, just according to different environment and term. So strong symbols correspond to strong references, and weak symbols correspond to weak references.

It can be seen from the above strong and weak references that when a function is a weak reference, no matter whether the function is defined or not, no error will be reported when linking, and we can judge whether the function name is 0 to decide whether to execute this function. In this way, the library containing these functions can be combined with our references in the form of modules, plug-ins, and easy to use and uninstall, and since strong symbols can override weak symbols and the relationship between strong and weak symbols and strong and weak references, it is wonderful that we can define our own functions to override the functions in the library.

Let's first judge whether to execute the function according to the condition:
Code, dc


 #include<stdio.h>
 
void func()
{
     printf("func()#1n");
}

Code e.c. with our fabrication:


 #include<stdio.h>
 
 __attribute__((weak)) void func();
 
 int main(int argc, char** argv)
 {
      if (func)
          func();
      return 0;
 }

C -c -c -c -c -c Compile e.c and link d.o, cc d.o.e.c-o.e output executable e, run e normal execution function func. Compile e.c without linking to d.o. No error will be reported, but func will not be executed because if(func) is false because there is no definition of it.
Now, function coverage:
Code f.


 #include<stdio.h>
 
 __attribute__((weak)) void func()
 {
      printf("func()#1n");
 }

Code right


 #include<stdio.h>
 
 void func()
 {
      printf("func()#2n");
  }
 
 int main(int argc, char** argv)
 {
      func();
      return 0;
 }
 ~      

Compile links, structure output "func()#2".

The above can explain that the function and the variable are consistent, in fact, the corresponding variable can also be used as a function to judge first and then use, but not to judge the value of the variable but the address of the variable, such as
Code v1. C


int i = 2;

Code v2. C


 #include<stdio.h>
 
 __attribute__((weak)) extern int i;
 
 int main(int argc, char** argv)
 {
      if (&i)
          printf("i = %dn", i);
     return 0;
 }
 ~      

When compiling and linking v1, output 2; No output when compiling without linking to v1. This is done by distinguishing between the definition and the declaration, s. S ((weak)) int I defines the variable and converts it to a weak sign, so that I is allocated space, whereas s ((weak)) extern int I converts the original defined variable I from a strong sign to a weak sign, resulting in a weak reference instead of a strong one when I is used. But even though a variable can do that, it doesn't make as much sense as a function.

The above mentioned weak reference still USES the GCC supplied s ((weak)), while the book also mentions s ((weakref)), which seems to be more of a reference. The reason why I use the former to introduce strong and weak references is because of my understanding of the correspondence between strong and weak symbols and strong and weak references. With respect to the usage method of arbitration ((weakref)), here is one (both have different usage methods).
Code a.c


 #include<stdio.h>
 
 void bar()
 {
      printf("foo()n");
 }

Code biggest


 #include<stdio.h>
 
 static void foo() __attribute__((weakref("bar")));
 
  int main(int argc, char** argv)
 {
      if (foo)
         foo();
 
      return 0;
 }

Notice the static modifier of the function foo, which will give an error if there is none, which limits the function foo to this file only.

Well, it's late in the night. It's a little messy. I'm messy.


Related articles: