Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是什么导致了几乎为空的.exe文件的重量?_C++_Compilation_Exe - Fatal编程技术网

C++ 是什么导致了几乎为空的.exe文件的重量?

C++ 是什么导致了几乎为空的.exe文件的重量?,c++,compilation,exe,C++,Compilation,Exe,我有以下代码片段: #include <iostream> using namespace std; int main(){ cout<<"Hi there!"; return 0; } 这又导致了一个137kb大小的可执行文件 虽然我知道137kb在现代计算中算不上什么,但就其运行的代码量而言,它似乎仍然是一个非常大的文件。此外,尝试编译一个类似的代码,但使用int变量会在顶部再增加15kb。编译过程中,整数会发生什么情况,以至于它的权重如此之大?您的代码将标准库的

我有以下代码片段:

#include <iostream>
using namespace std;

int main(){
cout<<"Hi there!";
return 0;
}
这又导致了一个137kb大小的可执行文件

虽然我知道137kb在现代计算中算不上什么,但就其运行的代码量而言,它似乎仍然是一个非常大的文件。此外,尝试编译一个类似的代码,但使用
int
变量会在顶部再增加15kb。编译过程中,整数会发生什么情况,以至于它的权重如此之大?

您的代码将标准库的IOstreams部分拉入,这是由Microsoft实现的。这意味着它还需要与C stdio同步,并支持globals的构造函数


此外,默认生成是调试生成。切换到测试的明显方式是
/O1
(优化大小)。未使用的整数变量应在发布版本中添加0字节
/DNDEBUG
应该消除断言。

这样考虑:


.cpp是一个草图,而.exe是一个工作机器,它必须打开一个控制台,写下你的字符串,才能终止自己。我相信这就是占用程序大部分空间的原因。

默认编译器选项将
MSVCRxxx.DLL
嵌入到可执行文件中,而使用/MD选项运行相同命令时不会发生这种情况:

cl.exe /MD /EHsc name.cpp
使用此命令,可执行文件大小为15KB(使用VS2013 x86本机工具)

这是因为默认情况下启动编译器的选项是
/MT
,而通过Visual Studio生成的项目的默认选项是
/MD
(导致文件接近15KB)。使用/MD选项,可执行文件更小,因为其中没有嵌入库

在两个单独的命令中编译和链接(默认的Visual Studio发行版解决方案配置命令):

这将生成将在下一个链接步骤中使用的对象文件

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的可执行文件

编译器选项可在下一个链接中找到:

虽然它可能看起来是一个非常小的可执行文件,但将在Linux中编译的同一个.cpp文件与g++进行比较,会发现有相当大的差异

g++name.cpp
->9,0KB可执行文件大小

并对其进行了一些优化:


g++-O2-s-DNDEBUG name.cpp
->6.3kb可执行文件大小

太神奇了,不是吗?想想那个狂躁的矿工在16k左右的时候滚了进来。@Bathsheba只用一个int(和额外的1K)变量构建一个游戏是一个神圣的关卡!我设法压缩到40kb,除了
intmain(){return 0;}
/O1
参数外,什么都没有。您描述的大约一半是由Windows本身完成的。Windows打开控制台。您必须向Windows提供字符串,但它随后会将该字符串写入控制台。终止是最复杂的,MSVCRT调用Windows
TerminateProcess
函数。但是从字面上看,这个调用最大的部分是名称“TerminateProcess”!调用本身约为8字节。是否可以进一步减轻重量?
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.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