博客專欄

EEPW首頁(yè) > 博客 > C++ 編譯過程簡(jiǎn)介

C++ 編譯過程簡(jiǎn)介

發(fā)布人:電子禪石 時(shí)間:2020-02-20 來源:工程師 發(fā)布文章

其中預(yù)處理 gcc -E hello.cpp  ,會(huì)把頭文件直接包含進(jìn)來,類似與直接拷貝過來。


yuchuli.PNG


//hi.c
#include "stdio.h"
void hi(void)
{
    printf("hi hi form c \n");
}
void second(void)
{
    printf("i am second \n");
}
//hi.h
#ifndef __HI_H__
#define __HI_H__

#ifdef __cplusepluse
extern "c"{
#endif
void hi(void);
void second(void);
#ifdef __cplusepluse
}
#endif
#endif

#include <iostream>
#include "hi.h"
using namespace std;
int main()
{
        hi();
        cout << "hello ,worle" << endl;
        return 0;
}

有個(gè)問題:如果hi.h中 不是 __HI_H會(huì)如何?上面的例子時(shí)沒有影響的。

主要就是定義了一個(gè)宏。

C/C++程序編譯流程:

預(yù)處理->編譯->匯編->鏈接

具體的就是:

源代碼(source coprede)→預(yù)處理器(processor)→編譯器(compiler)→匯編程序(assembler)→目標(biāo)程序(object code)→鏈接器(Linker)→可執(zhí)行程序(executables)

C語(yǔ)言在linux下的基本流程如圖:

89.png


1. 預(yù)處理

預(yù)處理相當(dāng)于根據(jù)預(yù)處理指令組裝新的C/C++程序。經(jīng)過預(yù)處理,會(huì)產(chǎn)生一個(gè)沒有宏定義,沒有條件編譯指令,沒有特殊符號(hào)的輸出文件,這個(gè)文件的含義同原本的文件無異,只是內(nèi)容上有所不同。


  • 讀取C/C++源程序,對(duì)其中的偽指令(以#開頭的指令)進(jìn)行處理


    ①將所有的“#define”刪除,并且展開所有的宏定義

    ②處理所有的條件編譯指令,如:“#if”、“#ifdef”、“#elif”、“#else”、“endif”等。這些偽指令的引入使得程序員可以通過定義不同的宏來決定編譯程序?qū)δ男┐a進(jìn)行處理。預(yù)編譯程序?qū)⒏鶕?jù)有關(guān)的文件,將那些不必要的代碼過濾掉。 

    ③處理“#include”預(yù)編譯指令,將被包含的文件插入到該預(yù)編譯指令的位置。

(注意:這個(gè)過程可能是遞歸進(jìn)行的,也就是說被包含的文件可能還包含其他文件)


  • 刪除所有的注釋



  • 添加行號(hào)和文件名標(biāo)識(shí)。


    以便于編譯時(shí)編譯器產(chǎn)生調(diào)試用的行號(hào)信息及用于編譯時(shí)產(chǎn)生的編譯錯(cuò)誤或警告時(shí)能夠顯示行號(hào)



  • 保留所有的#pragma編譯器指令


2. 編譯

將預(yù)處理完的文件進(jìn)行一系列詞法分析、語(yǔ)法分析、語(yǔ)義分析及優(yōu)化后,產(chǎn)生相應(yīng)的匯編代碼文件。

3. 匯編

將編譯完的匯編代碼文件翻譯成機(jī)器指令,并生成可重定位目標(biāo)程序的.o文件,該文件為二進(jìn)制文件,字節(jié)編碼是機(jī)器指令。

匯編器是將匯編代碼轉(zhuǎn)變成機(jī)器可以執(zhí)行的指令,每一個(gè)匯編語(yǔ)句幾乎都對(duì)應(yīng)一條機(jī)器指令。所以匯編器的匯編過程相對(duì)于編譯器來講比較簡(jiǎn)單,它沒有復(fù)雜的語(yǔ)法,也沒有語(yǔ)義,也不需要做指令優(yōu)化,只是根據(jù)匯編指令和機(jī)器指令的對(duì)照表一一翻譯即可。

4. 鏈接

通過鏈接器將一個(gè)個(gè)目標(biāo)文件(或許還會(huì)有庫(kù)文件)鏈接在一起生成一個(gè)完整的可執(zhí)行程序。

    由匯編程序生成的目標(biāo)文件并不能立即就被執(zhí)行,其中可能還有許多沒有解決的問題。

將生成的.obj文件與庫(kù)文件.lib等文件鏈接,生成可執(zhí)行文件(.exe文件)

例如,某個(gè)源文件中的函數(shù)可能引用了另一個(gè)源文件中定義的某個(gè)符號(hào)(如變量或者函數(shù)調(diào)用等);在程序中可能調(diào)用了某個(gè)庫(kù)文件中的函數(shù),等等。所有的這些問題,都需要經(jīng)鏈接程序的處理方能得以解決。

    鏈接程序的主要工作就是將有關(guān)的目標(biāo)文件彼此相連接,也就是將在一個(gè)文件中引用的符號(hào)同該符號(hào)在另外一個(gè)文件中的定義連接起來,使得所有的這些目標(biāo)文件成為一個(gè)能夠被操作系統(tǒng)裝入執(zhí)行的統(tǒng)一整體。

 

 

 

1.dll .obj .lib使用在windows平臺(tái)下

.dll:動(dòng)態(tài)鏈接庫(kù),作為共享函數(shù)庫(kù)的可執(zhí)行文件
.obj:對(duì)象文件,相當(dāng)于源代碼對(duì)應(yīng)的二進(jìn)制文件,未經(jīng)重定位
.lib:可理解為多個(gè)obj的集合,本質(zhì)與.obj相同

2 .so .o .a使用在linux平臺(tái)下

.so:(share object)動(dòng)態(tài)鏈接庫(kù),跟Windows平臺(tái)類似
.o: 對(duì)象文件,相當(dāng)于源代碼對(duì)應(yīng)的二進(jìn)制文件
.a: 與.o類似,多個(gè).o的集合


*博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。

dc相關(guān)文章:dc是什么




關(guān)鍵詞: C++

相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉