是什么导致了几乎为空的 .exe 文件的重量?
What accounts for the weight of nearly empty .exe file?
我有这个代码片段:
#include <iostream>
using namespace std;
int main(){
cout<<"Hi there!";
return 0;
}
我使用这一行通过 "Developer Command Prompt for VS2012" 编译的:
cl -GS name.cpp
这又产生了一个大小为 137kb 的可执行文件。
虽然我知道 137kb 在现代计算中不算什么,但对于它运行的代码量来说,它仍然是一个非常大的文件。此外,尝试编译类似的代码,但使用 int
变量会在顶部再增加 15kb。整数在编译过程中会发生什么,它必须有如此大的权重?
您的代码引入了 Microsoft 实施的标准库的 IOstreams 部分。这意味着它还需要与 C stdio 同步,并支持全局构造函数。
此外,默认构建是调试构建。明显的测试切换是 /O1
(针对大小进行优化)。未使用的整数变量应在发布版本中添加 0 个字节。 /DNDEBUG
应该消除断言。
这样想:
.cpp 是一个草图,而 .exe 是一个工作机器,它必须打开一个控制台,写下你的字符串,才能自行终止。我相信这就是大部分程序的 space.
默认编译器选项将 MSVCRxxx.DLL
嵌入到可执行文件中,不会发生的事情 运行 您使用 /MD 选项的相同命令:
cl.exe /MD /EHsc name.cpp
使用此命令,可执行文件大小为 15KB(使用 VS2013 x86 Native Tools)。
这是因为默认情况下启动编译器的选项是 /MT
,而通过 Visual Studio 构建的项目的默认选项是 /MD
(导致文件接近 15KB)。使用 /MD 选项,可执行文件较小,因为其中没有嵌入库。
在两个单独的命令中编译和 linking(默认 Visual Studio 发布解决方案配置命令):
cl /c /Zi /W3 /WX- /sdl /O2 /Oi /Oy- /GL /D WIN32 /D NDEBUG /D _CONSOLE /D _LIB /D _UNICODE /D UNICODE /Gm- /EHsc /MD /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Fo /Fd /Gd /TP /analyze- /errorReport:prompt name.cpp
这将生成将在下一步 link 中使用的目标文件。
link.exe /ERRORREPORT:PROMPT /OUT:"c:\Dev\namefromlinker.exe" /INCREMENTAL:NO /NOLOGO kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:"C:\Dev\name.pdb" /SUBSYSTEM:CONSOLE /OPT:REF /OPT:ICF /LTCG /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"c:\Dev\name.lib" /MACHINE:X86 /SAFESEH name.obj
这会生成一个 12KB 的可执行文件。
编译选项可以在下link:
中找到
https://msdn.microsoft.com/en-us/library/9s7c9wdw.aspx
虽然它可能看起来是非常小的可执行文件,但将在 Linux 中编译的相同 .cpp 文件与 g++ 进行比较显示出相当大的差异。
g++ name.cpp
-> 9,0KB 可执行文件大小
并稍微优化一下:
g++ -O2 -s -DNDEBUG name.cpp
-> 6,3 KB 可执行大小
我有这个代码片段:
#include <iostream>
using namespace std;
int main(){
cout<<"Hi there!";
return 0;
}
我使用这一行通过 "Developer Command Prompt for VS2012" 编译的:
cl -GS name.cpp
这又产生了一个大小为 137kb 的可执行文件。
虽然我知道 137kb 在现代计算中不算什么,但对于它运行的代码量来说,它仍然是一个非常大的文件。此外,尝试编译类似的代码,但使用 int
变量会在顶部再增加 15kb。整数在编译过程中会发生什么,它必须有如此大的权重?
您的代码引入了 Microsoft 实施的标准库的 IOstreams 部分。这意味着它还需要与 C stdio 同步,并支持全局构造函数。
此外,默认构建是调试构建。明显的测试切换是 /O1
(针对大小进行优化)。未使用的整数变量应在发布版本中添加 0 个字节。 /DNDEBUG
应该消除断言。
这样想:
.cpp 是一个草图,而 .exe 是一个工作机器,它必须打开一个控制台,写下你的字符串,才能自行终止。我相信这就是大部分程序的 space.
默认编译器选项将 MSVCRxxx.DLL
嵌入到可执行文件中,不会发生的事情 运行 您使用 /MD 选项的相同命令:
cl.exe /MD /EHsc name.cpp
使用此命令,可执行文件大小为 15KB(使用 VS2013 x86 Native Tools)。
这是因为默认情况下启动编译器的选项是 /MT
,而通过 Visual Studio 构建的项目的默认选项是 /MD
(导致文件接近 15KB)。使用 /MD 选项,可执行文件较小,因为其中没有嵌入库。
在两个单独的命令中编译和 linking(默认 Visual Studio 发布解决方案配置命令):
cl /c /Zi /W3 /WX- /sdl /O2 /Oi /Oy- /GL /D WIN32 /D NDEBUG /D _CONSOLE /D _LIB /D _UNICODE /D UNICODE /Gm- /EHsc /MD /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Fo /Fd /Gd /TP /analyze- /errorReport:prompt name.cpp
这将生成将在下一步 link 中使用的目标文件。
link.exe /ERRORREPORT:PROMPT /OUT:"c:\Dev\namefromlinker.exe" /INCREMENTAL:NO /NOLOGO kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:"C:\Dev\name.pdb" /SUBSYSTEM:CONSOLE /OPT:REF /OPT:ICF /LTCG /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"c:\Dev\name.lib" /MACHINE:X86 /SAFESEH name.obj
这会生成一个 12KB 的可执行文件。
编译选项可以在下link:
中找到https://msdn.microsoft.com/en-us/library/9s7c9wdw.aspx
虽然它可能看起来是非常小的可执行文件,但将在 Linux 中编译的相同 .cpp 文件与 g++ 进行比较显示出相当大的差异。
g++ name.cpp
-> 9,0KB 可执行文件大小
并稍微优化一下:
g++ -O2 -s -DNDEBUG name.cpp
-> 6,3 KB 可执行大小