C ++ compilation links

Source: Internet
Author: User

Several concepts to be understood: 1. Compile: the compiler compiles the source file, which is the process of translating the source code in the text form in the source file into the target file in the form of machine language, in this process, the compiler will perform a series of syntax checks. If the compilation is successful, the corresponding CPP will be converted to the OBJ file (in fact, the compilation seems to only generate an intermediate file, and then the assembler will generate the obj file ). 2. compilation unit: According to the C ++ standard, each CPP file is a compilation unit. Each compilation unit is independent and unknown to each other. 3. Target file: The file generated by the compilation contains all the code and data in the compilation unit in the form of a machine code, and some other information, such as the unresolved symbol table, export the symbol table and address redirection table. The target file exists in binary format. I plan to use an example to analyze the compilation link: Example 1:. cpp: [cpp] <span style = "font-size: 18px;"> int a </span> B. cpp: [cpp] <span style = "font-size: 18px;"> int a </span> when the two are compiled together, there is no problem (because the compilation is separate and there is no connection to each other), but there will be a problem during the link: B. obj: error LNK2005: "int "(? A @ 3HA) already defined in. obj analysis: both a are global variables, and the compiler will automatically initialize it to 0, which is equivalent to defining, not just declaration. during compilation, they will all put in. in the obj file symbol table, when two links are executed. the exported symbol table of the obj file has the symbol, so an error is reported. We noticed that the above red text shows that the definition and declaration are different. If you change one of them to Declaration, then OK. For example, A. cpp: extern int a; the extern keyword tells the compiler that n has been defined in another compilation unit, so do not define it in this unit. A is actually put into the "unsolved symbol table" of A. obj, that is, the unresolved symbol table. When the file is linked to the. exe file, only the symbols in all the unresolved symbol tables can be found in the export symbol table of other compilation units, and the link can pass. Similar to this example, a function is declared and used in a compilation unit, but defined in another compilation unit. Example 2:. cpp: [cpp] <span style = "font-size: 18px;"> static int a; </span> B. cpp: [cpp] <span style = "font-size: 18px;"> static int a; </span>. Analysis: If the keyword is located before the declaration of a global function or variable, it indicates that the compilation unit does not export this function or variable, because these symbols cannot be used in other compilation units (internal links ). If it is a static local variable, the variable is stored in the same way as the global variable, but the symbol is still not exported. The difference between an internal link and an external link: Check whether the symbol is written into the. obj file. For the const variable, the default internal link is used. Therefore, you can define the const variable as you write the static variable, but Initialization is required. Example 3: [cpp] <span style = "font-size: 18px;"> int a; void func () {int ;} </span> you can write such code. And it is very correct. Analysis: as explained above, global variable a is placed in the export symbol table, but what about local variable? It is managed by the stack and is not placed in the export symbol table. The following is a difficult analysis: header file and implementation file Example 4: c. h: [cpp] <span style = "font-size: 18px;"> class A {public: const int a; static int B; public: A (int num ): a (num) {} void test () ;}; </span> it makes no sense to discuss the const member here, only to familiarize yourself with the const member variables in the class and reference member variables (defined in intialization list ). Let's take a look at static int B. This is just a declaration (internal link ). It needs to be defined in another file, but this definition is an external link. What does it mean? A. cpp: [cpp] <span style = "font-size: 18px;"> int A: B = 1; </span> B. cpp: [cpp] <span style = "font-size: 18px;"> int A: B = 2; </span> An error is returned when the link is executed. Repeated definition A: B. Let's take a look at void test (). We generally implement this method in other files, such as: d. cpp: [cpp] <span style = "font-size: 18px;"> void A: test (){......} </span> if we need to use A, add # include "c. h. But what is the reason for the simplicity of everything? Analysis: the header file is just A declaration, declaring A class A, declaring A series of things in Class. The d. cpp file defines the test () method and writes the test symbol to the d. obj export symbol table. Other files can be linked using A a; a. test () and no error is reported. Everyone knows. cpp: # include "c. what does h mean: c. content in h appears in. in cpp, because the header file contains an internal link (not defined. cpp: # include "c. h "does not cause compilation link problems. But what if we don't put the implementation in another file? But in the header file? For example: [cpp] <span style = "font-size: 18px;"> class A {public: const int a; static int B; public: A (int num ): a (num) {} void test () ;}; void A: test () {cout <"A Class link is coming... "<endl ;}</span>. cpp: # include "c. h "B. cpp: # include "c. h "then there will be problems. Because the definition is an external link,. cpp contains test, B. cpp also contains test: B. obj: error LNK2005: "public: void _ thiscall A: test (void )"(? Test @ A @ QAEXXZ) already defined in. obj solution: declare it as the inline void test () function of the inline function, and define it in the header file, because the compilation units do not know each other during compilation, if inline is defined in. in the cpp file, you cannot find the function definition when compiling other compilation units that use this function, because some functions cannot be expanded. Therefore, if an inline function is defined in. cpp, only this. cpp file can use it. Through the study of compilation links, we can have a better understanding of those. lib and. dll files. Why. These files are actually the function definitions declared in our header files. We cannot introduce only the header files, and it is useless to find the definition. The APIs are basically provided to us through static and dynamic libraries. Let's take A look at the template compilation problem: Let's start with A simple example: 2.h: [cpp] template <class T> class A {public: int test (T a) ;}; 3.cpp: [cpp] # include <iostream >#include "2.h" template <class T> int A <T >:: test (T) {std: cout <"A test" <a <std: endl; return ;} 1.cpp: [cpp] # include <iostream> # include "2.h" void main () {A <int> a;. test (4);} Sorry to tell you that there is a problem with the link: [plain] view plaincopy1.obj: error LNK2001: unresolved external symb Ol "public: int _ thiscall A <int>: test (int )"(? Test @? $ A @ H @ QAEHH @ Z) Can't find the definition of test? Why? Aren't the general classes written in this way? Note that the template class is different from the general class compilation. Analysis: 1. cpp must have a statement of test (). The definition of test () occurs during the link. It is certain that 3. obj certainly does not have the definition of test () <---- This Is What we launched. Why is there no definition of test? According to the C ++ standard, a template should not be embodied when it is not used. What does it mean? 3. if A <int>: test () is not used in cpp, the binary code of the <int>: test () function will not be compiled to 3. in the obj file. If you still don't understand it, you can try it out: 3. cpp: [cpp] # include <iostream> # include "2.h" template <class T> int A <T >:: test (T a) {std :: cout <"A test" <a <std: endl; return a;} A <int> a; int g_a =. test (4); run it again and you will find that there are no problems .. Now, I must have understood what that sentence means. You will complain now. This is not professional! In fact, we can adopt the include compilation mode: The template definition can also be placed in the class: 2.h: [cpp] # include <iostream> template <class T> class A {public: int test (T a) ;}; template <class T> int A <T >:: test (T a) {std :: cout <"A test" <a <std: endl; return a;} is A bit like our inline function. The compilation link is OVER ..

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.