首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Hello World 背後的故事(一):編譯器選項、CRT 與入口點的真相

     編輯:關於C語言

引言:最熟悉的陌生人

printf("Hello World\n"); —— 這行代碼帶領無數程序員入門。但從源碼到可執行文件,再到進程啟動、CRT 初始化、最終進入 main,中間發生了什麼?本系列將剝開層層外衣,基於 **Windows 7 + Visual Studio 2010 (MSVC)** 環境,深入 CRT 源碼、反彙編與動態調試,還原程序完整生命週期。

1. 入口點之謎:main 還是 WinMain?

VS 專案屬性 Subsystem(子系統) 決定入口點:

Subsystem預定義宏連接器選項CRT 入口函數用戶入口
Console (/SUBSYSTEM:CONSOLE)_CONSOLE/SUBSYSTEM:CONSOLEmainCRTStartupmain / wmain
Windows (/SUBSYSTEM:WINDOWS)_WINDOWS/SUBSYSTEM:WINDOWSWinMainCRTStartupWinMain / wWinMain

關鍵認知:

  • 操作系統 Loader **只認 PE 標頭中的 AddressOfEntryPoint**,由連接器根據 /SUBSYSTEM 寫入 mainCRTStartup 或 WinMainCRTStartup。
  • CRT 入口函數(crt0.c 等)負責:**堆初始化、I/O 緩衝區建立、C++ 全局對象構造、命令行參數解析(argv/argc)、環境變量準備**,最後調用用戶入口(main/WinMain)。
  • main 返回值會被 CRT 捕獲並傳給 ExitProcess。

2. 字符集陷阱:Unicode vs MBCS

VS 專案屬性 Character Set 影響兩個維度:

  1. 編譯期宏:_UNICODE / _MBCS → 控制 TCHAR、_T()、Windows API 版本(MessageBoxW vs MessageBoxA)、CRT 字符串函數(_tcscpy 等)。
  2. 連接期入口選擇:由源碼中實際定義的入口函數名決定,而非宏!
    • 定義 int main() → 連接 mainCRTStartup
    • 定義 int wmain() → 連接 wmainCRTStartup
    • 同理 WinMain / wWinMain

    即:Character Set 宏只影響編譯,不影響連接器選擇哪個 CRT 入口。若專案設為 Unicode 但寫 main(),仍進入 ANSI 版 CRT 入口,命令行參數為 char**,需自行轉換。

3. CRT 鏈接模式:靜態 vs 動態

Runtime Library宏定義庫文件特點
/MT (Static Release)_MT, NDEBUGlibcmt.libCRT 代碼內嵌 EXE,體積大,無依賴,多 EXE 共享 CRT 狀態有風險
/MTd (Static Debug)_MT, _DEBUGlibcmtd.lib含調試檢查,體積更大
/MD (Dynamic Release)_MT, _DLL, NDEBUGmsvcrt.lib (導入庫)依賴 msvcrXXX.dll,體積小,系統級共享,需部署 VC++ Redistributable
/MDd (Dynamic Debug)_MT, _DLL, _DEBUGmsvcrtd.lib調試版 DLL 依賴

本系列聚焦 **靜態鏈接(/MT)** 下的 CRT 初始化流程(crt0.c 等),動態鏈接(crtexe.c)略有不同(由 DLL 入口點 DllMain 觸發初始化)。

4. 本文小結與下期預告

Hello World 的「隱形冰山」:

  • Subsystem → 連接器選擇 CRT 入口(mainCRTStartup/WinMainCRTStartup)
  • Character Set → 編譯期宏,不決定入口,入口由函數簽名決定
  • Runtime Library → 決定 CRT 代碼內嵌還是外部 DLL,影響初始化實現文件

下期預告:從 CreateProcess 到主執行緒啟動,再到 mainCRTStartup 具體做了什麼(堆、I/O、全局構造、SEH、參數解析……),敬請期待。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved