VC++ 編譯過程

來源:互聯網
上載者:User

標籤:

一 前言

以前在編譯C++代碼的時候對編譯的錯誤都覺得很難理解,搞不清楚究竟是哪裡錯了。後來C++寫多了,總結了一些經驗,然後也瞭解了一下編譯過程,但是沒有系統的對編譯過程進行學習,現在趁著寫部落格的機會,好好的把編譯過程寫下來,並且理順一下這個知識點。

二 名詞解釋

編譯單元:當一個c或cpp檔案在編譯時間,前置處理器首先遞迴包含標頭檔,形成一個含有所有 必要資訊的單個源檔案,這個源檔案就是一個編譯單元。

目標檔案:目標檔案包含著機器代碼(可直接被電腦中央處理器執行)以及代碼在運行時使用的資料,此外還包括其他調試資訊。

三 編譯過程

在VC中編譯過程會分成以下三步:

1,預先處理
2,產生目標檔案
3,連結成可執行檔

 

1,預先處理

將標頭檔載入進來,處理各種#define,如:宏,先行編譯條件,產生一個獨立的編譯單元。

可以通過以下的命令來產生獨立的編譯單元。

cl /EP test.cpp > test_p.cpp

這個命令的意思是,把源檔案產生編譯單元並寫到test_p.cpp中。舉個例子

下面是源檔案代碼

// test.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <windows.h>#include <iostream>#define MAX(a,b)    (a>b?a:b)#define PI    3.1415927#ifdef UNICODEtypedef wchar_t MTCHAR;#elsetypedef char    MTCHAR;#endif // UNICODE
int _tmain(int argc, _TCHAR* argv[]){    std::cout << MAX(10, 20) << std::endl;    std::cout << PI << std::endl;    MTCHAR *str = _T("hello world!");    _tprintf(_T("%s\n"), str);    return 0;}

原始碼中包含了三個標頭檔,定義一個運算式的宏,一個常量的宏,和使用先行編譯條件定義了一個字元類型

我們通過上面的命令產生新的檔案,包含檔案指令會把標頭檔引進來,把宏在代碼中替換掉,把先行編譯條件指令處理。

/*這裡省略掉大量的標頭檔代碼,整個檔案總共有三十多萬行。*/typedef char    MTCHAR;int main(int argc, _TCHAR* argv[]){    std::cout << (10>20?10:20) << std::endl;    std::cout << 3.1415927 << std::endl;    MTCHAR *str = "hello world!";    printf("%s\n", str);    return 0;}

也可以在cl命令中加入宏UNICODE和_UNICODE,這樣可以更清晰地看到預先處理條件指令的處理效果

cl /EP /D "UNICODE" /D "_UNICODE" test.cpp > test_p.cpp

產生的編譯單元

/*這裡省略掉大量的標頭檔代碼,整個檔案總共有三十多萬行。*/typedef wchar_t MTCHAR;int wmain(int argc, _TCHAR* argv[]){    std::cout << (10>20?10:20) << std::endl;    std::cout << 3.1415927 << std::endl;    MTCHAR *str = L"hello world!";    wprintf(L"%s\n", str);    return 0;}

MTCHAR已經被定義為wchar_t而不是char了,而且字串也是wchar格式。

 

2,產生目標檔案

將編譯單元進行編譯,產生目標檔案(.obj檔案)。這裡通常分兩個階段:首先產生組合語言,然後適用彙編產生機器碼。

通過剛才產生的編譯單元來產生目標檔案

cl /c test_p.cpp

已經產生裡機器碼,所以不貼檔案內容了。

3,連結

連結的任務就是把目標檔案連起來產生可執行檔。

link test.obj

使用這個命令就能產生exe檔案。

4,cl命令

cl命令有幾個跟標準庫有關的選項:/ML,/MLd,/MT,/MTd,/MD,/MDd。這些選項是想告訴編譯器應用程式需要什麼標準庫。

/ML:(預設選項)對應單線程靜態標準庫。

/MT:對應多線程靜態標準庫 (libcmt.lib) ,此時編譯器會自動定義 _MT 宏。

/MD:對應多線程 DLL 版 ( 匯入庫 msvcrt.lib , DLL 是msvcrt.dll) ,編譯器自動定義 _MT 和 _DLL兩個宏。
/MLd:對應調試單線程靜態標準庫 (libcd.lib) 。
/MTd:對應調試多線程靜態標準庫 (libcmtd.lib) 。
/MDd:對應調試多線程 DLL 標準庫 ( 匯入庫msvcrtd.lib, DLL 是msvcrtd.dll) 。

VC++ 編譯過程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.