The GCC/LD compilation link has many potential rules. If you are not aware of this hidden rule, it will take a long time to debug it. the following summarizes some of the potential rules I have encountered.
This article is the first release, and other potential rules will be released one after another.
Potential rules:
When a symbol appears in multiple target files (. O) at the same time, LD reports an error. Multiple definitions of symbols are prompted.
When a symbol appears in multiple static libraries (. A) at the same time, LD does not report an error. The first encountered symbol prevails. No warning is reported.
!!! This potential rule may cause many unexpected problems !!!
Test code:
Helper. h
Helper1.cpp
Helper2.cpp
Symbol_in_multi_obj.cpp
Compile command:
Test results:
An error occurred while linking the. o file. The system prompts the symbol to be redefined.
The link to file. A is successful, but the link is actually the symbol in the first..
First link helper1.a and output "Call myfun in helper1.cpp"
First link helper2.a and output "Call myfun in helper2.cpp"
Real case:
Shasha calls the http_request_helper class in the CGI class to send a request. It finds that the program behavior is always inconsistent with the expectation. Later, it finds that there is another dependent library in makefile (. a) The http_request_helper class is also packaged, but the implementation of the class is relatively old, resulting in overwriting the new library later!Gcc/LD does not remind you of this !!! Shit.
Add a supplement from perryyang:
Add:
Gcc/LD in
1. When parsing symbols, the code of the first definition will be linked in (if the code has been found, the subsequent code will not be considered)
2. when linking objects (*. o file), each target file needs to perform the reloc operation, find the first definition to take priority, and then encounter the same definition, it will report "multip-definition error ", this can be solved through-wl, '-Z muldefs,
-Z muldefs will allow LD to process only the first definition in case of repeated definitions.
If:
1. If there are multiple identical dynamic database names, find the path according to the library configured in ldconfig and select which one to use first. If there are dynamic libraries of different versions on the machine, the wrong library may be used, but the error cannot be checked from our code,
Only the "ldconfig-p | grep database name" check can be performed first, and only one unused database can be killed.
2. if multiple dynamic libraries have the same global variable name, the global variables in the last loaded dynamic library will overwrite the previously loaded global variables, resulting in an exception (the program works properly)
The following is a metaphor for Link processing:
Http://webpages.charter.net/ppluzhnikov/linker.html
Comparison with VC ++
In addition, the comparison of VC ++ behavior is different. When multiple dependent libraries have the same name symbol, VC ++ will re-define the symbol instead of selecting one by default. at the same time, VC ++ also provides the ability to ignore the specified library when the symbol is redefined.
The GCC/LD compilation link has many potential rules. If you are not aware of this hidden rule, it will take a long time to debug it. the following summarizes some of the potential rules I have encountered.
This article is the first release, and other potential rules will be released one after another.
Potential rules:
When a symbol appears in multiple target files (. O) at the same time, LD reports an error. Multiple definitions of symbols are prompted.
When a symbol appears in multiple static libraries (. A) at the same time, LD does not report an error. The first encountered symbol prevails. No warning is reported.
!!! This potential rule may cause many unexpected problems !!!
Test code:
Helper. h
Helper1.cpp
Helper2.cpp
Symbol_in_multi_obj.cpp
Compile command:
Test results:
An error occurred while linking the. o file. The system prompts the symbol to be redefined.
The link to file. A is successful, but the link is actually the symbol in the first..
First link helper1.a and output "Call myfun in helper1.cpp"
First link helper2.a and output "Call myfun in helper2.cpp"
Real case:
Shasha calls the http_request_helper class in the CGI class to send a request. It finds that the program behavior is always inconsistent with the expectation. Later, it finds that there is another dependent library in makefile (. a) The http_request_helper class is also packaged, but the implementation of the class is relatively old, resulting in overwriting the new library later!Gcc/LD does not remind you of this !!! Shit.
Add a supplement from perryyang:
Add:
Gcc/LD in
1. When parsing symbols, the code of the first definition will be linked in (if the code has been found, the subsequent code will not be considered)
2. when linking objects (*. o file), each target file needs to perform the reloc operation, find the first definition to take priority, and then encounter the same definition, it will report "multip-definition error ", this can be solved through-wl, '-Z muldefs,
-Z muldefs will allow LD to process only the first definition in case of repeated definitions.
If:
1. If there are multiple identical dynamic database names, find the path according to the library configured in ldconfig and select which one to use first. If there are dynamic libraries of different versions on the machine, the wrong library may be used, but the error cannot be checked from our code,
Only the "ldconfig-p | grep database name" check can be performed first, and only one unused database can be killed.
2. if multiple dynamic libraries have the same global variable name, the global variables in the last loaded dynamic library will overwrite the previously loaded global variables, resulting in an exception (the program works properly)
The following is a metaphor for Link processing:
Http://webpages.charter.net/ppluzhnikov/linker.html
Comparison with VC ++
In addition, the comparison of VC ++ behavior is different. When multiple dependent libraries have the same name symbol, VC ++ will re-define the symbol instead of selecting one by default. at the same time, VC ++ also provides the ability to ignore the specified library when the symbol is redefined.