博客專欄

        EEPW首頁 > 博客 > C++ 編譯過程簡介

        C++ 編譯過程簡介

        發布人:電子禪石 時間:2020-02-20 來源:工程師 發布文章

        其中預處理 gcc -E hello.cpp  ,會把頭文件直接包含進來,類似與直接拷貝過來。


        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;
        }

        有個問題:如果hi.h中 不是 __HI_H會如何?上面的例子時沒有影響的。

        主要就是定義了一個宏。

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

        預處理->編譯->匯編->鏈接

        具體的就是:

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

        C語言在linux下的基本流程如圖:

        89.png


        1. 預處理

        預處理相當于根據預處理指令組裝新的C/C++程序。經過預處理,會產生一個沒有宏定義,沒有條件編譯指令,沒有特殊符號的輸出文件,這個文件的含義同原本的文件無異,只是內容上有所不同。


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


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

            ②處理所有的條件編譯指令,如:“#if”、“#ifdef”、“#elif”、“#else”、“endif”等。這些偽指令的引入使得程序員可以通過定義不同的宏來決定編譯程序對哪些代碼進行處理。預編譯程序將根據有關的文件,將那些不必要的代碼過濾掉。 

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

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


        • 刪除所有的注釋



        • 添加行號和文件名標識。


          以便于編譯時編譯器產生調試用的行號信息及用于編譯時產生的編譯錯誤或警告時能夠顯示行號



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


        2. 編譯

        將預處理完的文件進行一系列詞法分析、語法分析、語義分析及優化后,產生相應的匯編代碼文件。

        3. 匯編

        將編譯完的匯編代碼文件翻譯成機器指令,并生成可重定位目標程序的.o文件,該文件為二進制文件,字節編碼是機器指令。

        匯編器是將匯編代碼轉變成機器可以執行的指令,每一個匯編語句幾乎都對應一條機器指令。所以匯編器的匯編過程相對于編譯器來講比較簡單,它沒有復雜的語法,也沒有語義,也不需要做指令優化,只是根據匯編指令和機器指令的對照表一一翻譯即可。

        4. 鏈接

        通過鏈接器將一個個目標文件(或許還會有庫文件)鏈接在一起生成一個完整的可執行程序。

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

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

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

            鏈接程序的主要工作就是將有關的目標文件彼此相連接,也就是將在一個文件中引用的符號同該符號在另外一個文件中的定義連接起來,使得所有的這些目標文件成為一個能夠被操作系統裝入執行的統一整體。

         

         

         

        1.dll .obj .lib使用在windows平臺下

        .dll:動態鏈接庫,作為共享函數庫的可執行文件
        .obj:對象文件,相當于源代碼對應的二進制文件,未經重定位
        .lib:可理解為多個obj的集合,本質與.obj相同

        2 .so .o .a使用在linux平臺下

        .so:(share object)動態鏈接庫,跟Windows平臺類似
        .o: 對象文件,相當于源代碼對應的二進制文件
        .a: 與.o類似,多個.o的集合


        *博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。

        dc相關文章:dc是什么




        關鍵詞: C++

        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 巴楚县| 苏州市| 海阳市| 正安县| 两当县| 泌阳县| 松阳县| 华宁县| 额尔古纳市| 平罗县| 太康县| 揭东县| 敦煌市| 中超| 桦甸市| 高青县| 嵊州市| 洛阳市| 开平市| 潮安县| 横峰县| 浦东新区| 双城市| 玉屏| 江口县| 胶南市| 车险| 乡城县| 翁牛特旗| 娱乐| 西平县| 天镇县| 长顺县| 南京市| 天气| 衡山县| 汽车| 满洲里市| 阿图什市| 根河市| 宁安市|