Wednesday, August 4, 2010

C + + compiler on the template of separate answers to questions

First of all, C + + standard that a compilation unit [translation unit] is a. Cpp file and include it all. H files,. H file in the code will be extended to include it. Cpp file, and then compile the compiler. cpp file as a. obj file, which has a PE [Portable Executable, the windows executable file] file format, and contains in itself already is a binary code, but may not be able to perform, as and does not guarantee there will be one main function. When the compiler will be a project in all. Cpp files to compile separate ways after, then the connector (linker) to connect to a. Exe file.

For example:

//--------------- Test.h-------------------//

void f ();// here to declare a function f

//--------------- Test.cpp--------------//

# Include "test.h"

void f ()


... / / Do something

) / / Here to achieve the function f declared test.h

//--------------- Main.cpp--------------//

# Include "test.h"

int main ()


f (); / / call f, f is the external connection type

In this case, test. Cpp and main.cpp is compiled into various different. Obj file [name test.obj throw and main.obj], in the main.cpp, calling the f function, but when the compiler main.cpp time, just know that it is only main.cpp contained in the test.h file in the one on void f (); the statement, the compiler will be here, f as the external connection type, or that Its function is to achieve the code in another. obj file, in this case is test.obj, that is, main.obj actually not even a line on the f function of the binary code, and these codes are actually present in test.cpp compiled into the test.obj in. In main.obj call on f command will generate a line call, like this:

call f [C + + in the name of course, after mangling [deal] off]

At compile time, this call instruction is clearly wrong, because there is no line f main.obj the implementation code. Then how should we do? This is the task of the connector, connectors for the other. Obj in [this case test.obj] f the implementation code search to find the instruction after the call f replaced by a call to address the actual entry point address of the function f . Note that: the connector will actually work inside. Obj "connection" has become a. Exe file, and its most critical task is said above, look for an external connection symbol in the other. Obj in the address, then replace the original "false" address.

If this process is a more in-depth:

call f command line but it is not, it is actually the so-called stub, which is a jmp 0x23423 [This address may be arbitrary, but the key is that there is a line command to address a genuine call f action. That is, the. Obj file which calls all of the f, jmp to the same address, in which there really "call" f. This has the advantage that changes of address as long as the connector on the latter's call XXX address for changes on the line. But how to find the f connector is the actual address it [in this case, it is test.obj in].

Because. Obj to. Exe format is the same, in such a file into a symbol table and symbol export table [import table and export table] which will address all the symbols and their associates. This connector as long as the export table in test.obj find symbol symbol f [of course, C + + on f were mangling] address on the line, and then make some offset treatment [because it is two. Obj files into, of course, address will have a certain offset, the connector clear] write main.obj the symbols into the table f occupied by the last one.
This is about process. The key is:

Main.cpp compiled, the compiler does not know f the realization of it all when it comes to just give a call instruction, the connector should be directed to find f for its implementation body. This means that main.obj not on any line of binary code f.

Compile test.cpp, the compiler found a f implementation. Ever since the realization of f [binary code] in test.obj years.

Connection, the connector found in test.obj f the implementation code [binary] address [derived through symbol table]. Then the pending call XXX main.obj address into f the actual address.


However, the template, you know, actually the code template function can not be directly compiled into binary code, which must be of a "modernization" process. For example:

//---------- Main.cpp------//


void f (T t)


int main ()


... / / Do something

f (10); / / call f decided to give the compiler where f is a body of concrete f

... / / Do other thing



That is, if you had not called main.cpp file, f, f is also not specific to main.obj in f there is no arbitrary line on the binary code! ! If you call this:

f (10); / / f to come out with is of

f (10.0); / / f to come out with is of

This main.obj in and will have a f, f are two functions of the binary code. And so on.

But with the current requirements of the compiler know that the template definition, is not it?

See the following example: [to separate the template and its implementation]

//------------- Test.h----------------//


class A



void f (); / / here is a statement


//--------------- Test.cpp-------------//

# Include "test.h"


void A:: f () / / template to achieve, but note: not with the current


... / / Do something


//--------------- Main.cpp---------------//

# Include "test.h"

int main ()


A a;

af (); / / Here the compiler does not know A:: f of the definition because it is not test.h inside

/ / So compiler can only hopes the connector so that it might in others. Obj to find something

/ / A:: f the implementation body, in this case is test.obj, however, the latter really have A:: f the

/ / Binary code? NO! ! ! Because C + + standard clearly that when a template is not used when

/ / Hou it should not be a stand out, test.cpp used in the A:: f it? No! ! So Real

/ / Test.cpp compiled on the occasion of the test.obj file on A:: f the line of binary code has not

/ / Then the connector was stoned, and had to give a connection error

/ / However, if you write a function in test.cpp, which calls A:: f, the compiler will it / / with stand out, because at this point [test.cpp in], the compiler know the template definition, they are able to / / enough with current technology, therefore, test.obj symbol export table will have a A:: f the address of this symbol, so the connector will be able to complete the task.


The key is: separate compilation environment, the compiler compile one. Cpp file does not know the other. Cpp file exists, it will not find [When faced with hopes it will open symbols connected device]. This model case in the absence of the template works well, but the encounter template was stoned, because the template only when needed will come with modernization, so when the compiler can only see the template declaration, it can not a modernization of the template, can only create a symbolic link with the external connector and look forward to be able to sign out the address resolution.

However, when the realization of the template. Cpp file does not use the template with the current body, the compiler is too lazy to go with, so the whole project. Obj can not find a line on the template with the current body of binary code, then connect devices are dumbfounded! (CSDN)

Recommended links:

Assembly Instructions And The Machine Code Of Each Conversion

Vocational Education Experts: Freshman Should Foster Professional Ideas


convert .MOV to .avi

Free sharing OF Ubuntu

what is mkv

mov to AVI converter

Photoshop combat KPT7 (1)

2009IT affect CHINA - moved to action

Specialist Install And Setup

comparison Project Management

Suspected of extortion Donews producer Liu Ren denies allegations

Why is throwing money at very odd tiger VC Zhou Hongyi good "FUDGE"?


Teaching And Training Tools Guide

Flash Visual Effects Of The Space Shuttle

FreeBSD Command Ps Introduction

No comments:

Post a Comment