Because I have been busy reviewing exams recently, my reading notes have fallen. Now I only have the last single-chip microcomputer. I still have four days to review?
Wait until the last day .~~ Slowly, I am used to this rhythm and like the heartbeat of the bare test ~
There are still a lot of related knowledge about the target file. What I can do is to select the desired knowledge to learn (in fact, I can understand it and learn it at the time ).
If you do not waste it, you should select the knowledge that is worth learning and master it in general. This may be contrary to the initial starting point for studying the details of these compilation links,
The initial goal was to find out the details, but from another point of view, the focus was on compilation and linking. Ignoring the small details is also
Acceptable ).
1. How can we extend the concepts of symbol modification and function signature?
John has carefully thought about this problem, but finally he chose to summarize the language in the book and then extended the problem. If you read this article
Xiaowen: If you are not satisfied with it, please make a brick. Xiaosheng received criticism and education here.
1. Background and conditions for symbolic modification and function signature creation:
In 1970s, the compiler compiledSource codeWhen the target file is generated, the symbol is the same as the corresponding variable and function name. Later, the UNIX platform and C Language
At the time of invention, there were already a considerable number of libraries and target files written using assembler. This problem arises, a CProgramC Language
The names of functions and variables defined in these libraries cannot be used as symbol names. Otherwise, they will conflict with the existing target file.
In order to prevent similar symbol name conflicts, the C language in UNIX stipulates that the C language sourceCodeCorresponding Symbol names after all global variables and functions are compiled
Underlines (_) are added before and after the source code of the Fortran language is compiled, "_" is added before and after all symbols "_".
This simple and original method can reduce the probability of symbol conflicts between target files in multiple languages temporarily, but it does not fundamentally solve the problem of symbol conflicts.
A. Different symbol constraints are added to the target file generated after source code compilation in different languages, but the symbol conflicts in the same language are still unsolved.
B. Due to the cause of collaborative development of modules, there is a higher probability of symbol conflicts. To reduce conflicts, we need to develop complicated and cumbersome coding specifications.
In addition, these jobs seem useless and time-consuming.
In this regard, we can verify that GCC provides the compilation parameter "-fleading-underscore"/"-fno-leading-underscore" to enable or disable the generation.
Dashes. A simple helloworld. C program:
# Include <stdio. h> # include <stdlib. h> // global test varint global_test_var = 100; // test methodvoid test_method (); int main (INT argc, char * argv []) {test_method (); printf ("% s \ n", "helloworld"); Return exit_success;} void test_method () {printf ("% s \ n", "test method! "); Return ;}
Use the readelf tool to view the information in the generated target file.
We can see that the underline is generated before the global variables and function methods.
2. Name modification is closely related to the birth of the function signature and C ++:
Many people know that C ++ is very complicated and has many complicated mechanisms and features. Sometimes we will fall in love with these mechanisms and features, and sometimes let me
These features, such as class, inheritance, virtual mechanism, overload, and namespace, make symbol management more complex.
Modification and function signature. As for the details, I think there is no need to discuss them. The principle is very simple:
Name modification and function signature are used to avoid symbol conflicts. Some mechanisms are used to keep the symbols in the source code in the generated target file.
Uniqueness ensures uniqueness, which weakens and eliminates the possibility of conflict. Is it easy? Well, at least the principle is very simple. The specific implementation mechanism should be
It is quite complicated. I will not make any guesses here.
You can use the readelf tool to view the content information in the target file and the changes made to the symbol by the compiler after compilation. Then verify the name modifier and function.
The signature mechanism is also a simple program:
# Include <iostream> namespace sample_namespace {int sample_var = 10; typedef int sample_int; Class sample_class {
Sample_class (simple_int parm): sample_parm (parm ){}
Int sample_func (INT sample_parm1, double sample_parm2); sample_int sample_parm ;};} int main (INT argc, char * argv []) {return 0 ;}
This small program is indeed very simple. The following uses a tool to view the information in the generated target file:
(Sorry, I can't see anything...) I'm not afraid. There are other tools. We use objdump.
Here we can see _ global _ sub_ I _ zn16sample_namespace10sample_vare IN THE. text section. Well, no matter what this is, let's take a look.
Assembly code:
Well, it is clear here. Here we will explain this: _ zn16sample_namespace10sample_vare
This is generated by the name modification mechanism. This looks unclear, but it can be explained using a tool: C ++ filt _ zn16sample_namespace10sample_vare
The result is simple, but our sample_namespace: sample_var.
Iii. extern "C"
In fact, extern "C" is a keyword that provides C-compatible keywords for C ++.
The C ++ compiler treats all the code in the scope of the extern "C" braces as a C language. Therefore, the name modification and function signature mechanism of the corresponding C ++ do not work.
In many ides, some basic work is well done when creating a source file. Some code compatible with C ++ is also automatically generated:
# Ifdef _ cplusplusextern "C" {# endif // XXXX # ifdef _ cpluspus} # endif
These skills are useful in many libraries and are common.
Since the statements modified by the keyword extern "C" are not processed by the C ++ name during execution, assume that:
We understand the mechanism of C ++ name modification.
So we can try to add a name-modified statement in the Code and use the extern "C" modifier. How can this problem be solved?
The presentation capability is limited. For example:
Just like in the above example, rewrite some code:
Extern "C" int _ Empty; int main (INT argc, char * argv []) {using namespace STD; cout <_ zn16sample_namespace10sample_vare <Endl; return 0 ;}
What will happen to this result? The namespace sample_namespace is not referenced in the processing process, but the simple_var variable is output.
The result is successful, and the output is successful: 10.
I have done my best to summarize my reading and data query results. The main purpose is to summarize the results. If you see this articleArticle,
In addition, you will be able to get a little bit of attention. If you think that writing is not good, please forgive me ~~