代码之家  ›  专栏  ›  技术社区  ›  Misha.P

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

  •  2
  • Misha.P  · 技术社区  · 9 年前

    我有以下代码片段:

    #include <iostream>
    using namespace std;
    
    int main(){
    cout<<"Hi there!";
    return 0;
    }
    

    我通过“VS2012的开发人员命令提示符”使用以下命令行编译:

    cl -GS name.cpp
    

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

    3 回复  |  直到 9 年前
        1
  •  3
  •   MSalters    9 年前

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

    此外,默认生成是调试生成。显然,转向测试将是: /O1 (优化尺寸)。未使用的整数变量应在发布版本中添加0字节。 /DNDEBUG 这应该消除断言。

        2
  •  1
  •   jgorostegui    9 年前

    默认编译器选项嵌入 MSVCRxxx.DLL 在可执行文件中,使用/MD选项运行相同命令时不会发生的事情:

    cl.exe /MD /EHsc name.cpp
    

    使用此命令,可执行文件大小为: 15KB (使用VS2013 x86本机工具)。

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

    在两个独立的命令中编译和链接(默认的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.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 .

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

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

        3
  •  0
  •   Matt_Caner    9 年前

    这样想:

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