簡體   English   中英

用於最小可執行文件的 C++ Windows 編譯器

[英]C++ Windows Compiler for smallest executables

伙計們,我想開始用 C++ 編程。 我已經用 vb6、vb.net 編寫了一些程序,現在我想獲得 C++ 知識,我想要一個可以將我的代碼編譯成最小的 Windows 應用程序的編譯器。 例如,有一個名為 PureBasic 的 Basic 語言編譯器,它可以使 Hello world 獨立應用程序的大小為 5 kb,而我編譯的簡單套接字程序只有 12kb(沒有任何 DLL-s 和運行時文件)。 我知道這太棒了,所以我想要 C++ 類似的東西。

如果我錯了並且沒有這種 Windows 編譯器,有人可以給我一個網站或書籍來教我如何減少 C++ 可執行文件的大小,或者如何使用 Windows API 調用?

例如 Microsoft Visual C++ 編譯器...您只需關閉與 C 運行時 ( /NODEFAULTLIB ) 的鏈接,您的可執行文件將小至 5KB。 只有一個問題:您將無法使用標准 C 和 C++ 庫中的幾乎任何東西,也無法使用 C++ 的標准特性,如異常處理、 newdelete運算符、浮點運算等。 您只需要使用純操作系統功能(例如,使用CreateFile創建文件,使用HeapAlloc分配內存等...)。

很多年前我不得不用 VC6 來做這件事。 這是必要的,因為可執行文件將通過線路傳輸到目標計算機,並在其中運行。 由於它很可能通過調制解調器連接發送,因此它需要盡可能小。 為了縮小可執行文件,我依靠兩種技術:

  1. 不要使用 C 或 C++ 運行時。 告訴編譯器不要鏈接它們。使用 Windows API 的子集實現所有必要的功能,該子集保證在當時的所有 Windows 版本上都可用(98,Me,NT,2000)。
  2. 告訴鏈接器將所有代碼和數據段合並為一個。 我不記得這個開關,我不知道它是否仍然可能,特別是對於 64 位可執行文件。

最終可執行文件大小:~2K

在 Visual C++ 中將以下代碼的可執行文件大小從 24k 字節減少到 1.6k 字節

int main (char argv[]) {
  return 0;
}
  1. 鏈接器開關(盡管建議安全對齊為 512):

/文件對齊:16 /對齊:16

  1. 鏈接(在 VC++ 項目屬性中):LIBCTINY.LIB

  2. 額外的編譯指示(這將解決 Feruccio 的建議)

但是,我仍然看到一段 ASCII(0) 構成了三分之一的可執行文件,以及“豐富的”Windows 簽名。 (我正在閱讀后者並不是程序執行所真正需要的)。

#ifdef NDEBUG
#pragma optimize("gsy",on)
#pragma comment(linker,"/merge:.rdata=.data")
#pragma comment(linker,"/merge:.text=.data")
#pragma comment(linker,"/merge:.reloc=.data")
#pragma comment(linker,"/OPT:NOWIN98")
#endif // NDEBUG
int main (char argv[]) {
  return 0;
}

我不知道你為什么在學習語言之前對這種優化感興趣,但無論如何......

它對你使用的編譯器沒有太大的影響,但你如何使用它。 例如,選擇像 Visual Studio C++ 或 MinGW 這樣的編譯器,並閱讀其文檔。 您將找到有關如何針對大小或性能優化編譯的信息(通常當您針對大小進行優化時,您會失去性能,反之亦然)。

例如,在 Visual Studio 中,您可以通過將 /O1 參數傳遞給編譯器(或 Project Properties/C-C++ /Optimization)來最小化可執行文件的大小。

另外不要忘記在“發布”模式下編譯,否則您的可執行文件可能會充滿調試符號,這會增加您的可執行文件的大小。

運行 Windows 的現代台式 PC 至少有 1Gb RAM 和巨大的硬盤驅動器,擔心不代表任何實際應用程序的瑣碎程序的大小是沒有意義的。

任何語言的“Hello world”程序的大部分大小都是固定開銷,用於建立執行環境以及加載和啟動代碼。 對於任何重要的應用程序,您應該更關心代碼大小隨着添加更多功能而增加的速度。 從這個意義上說,任何編譯器中的 C++ 代碼都非常高效。 也就是說,您的 PureBasic 程序很少或不執行任何操作可能比等效的 C++ 程序小,但是當您在代碼中構建有用的功能時,情況不一定如此。

@user:C++ 確實會生成小目標代碼,但是如果 printf() (或 cout<<) 的代碼是靜態鏈接的,則生成的可執行文件可能會更大,因為 printf() 有很多功能在“hello world”程序是多余的。 嘗試使用 puts() 例如,您可能會發現代碼更小。

此外,您確定將蘋果與蘋果進行比較嗎? 一些執行環境依賴於動態鏈接的運行時庫或虛擬機,它們提供的功能可能在 C++ 程序中靜態鏈接。

我不喜歡回復死帖,但由於沒有回復提到這一點(除了 Mat 回復)......

在我之后重復:C++ != ( vb6 || vb.net || basic )。 而且我不僅提到語法,C++ 編碼風格通常與 VB 中的不同,因為 C++ 程序員試圖讓事情通常比 vb 程序員設計得更好......

PS:不,在 C++ 世界中沒有復制粘貼的地方。 對不起,不得不說這個……

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM