c++ 为什么可执行文件这么大? (为什么没有删除死代码?)

编译和链接此文件将导致1 KiB可执行文件:

#pragma comment(linker, "/Entry:mainCRTStartup") // No CRT code (reduce size)
#pragma comment(linker, "/Subsystem:Console")    // Needed if avoiding CRT

#define STRINGIFIER(x)    func##x
#define STRINGIFY(x)      STRINGIFIER(x)
#define G   int STRINGIFY(__COUNTER__)(void) { return __COUNTER__; }

int mainCRTStartup(void) { return 0; }  // Does nothing

#if 0
    // Every `G' generates a new, unused function
    G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G
    G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G G

当您将#if 0更改为#if 1)时,输出大小加倍至2 KiB。

尽管我的命令行选项包含了我可以想到的所有优化,但它似乎与迄今为止所有版本的Visual C都这样做:

/Ox /MD /link /fixed /OPT:ICF /OPT:REF


有人知道为什么/ OPT:REF不会导致链接器删除未使用的函数?






LINK removes unreferenced packaged functions by default. An object contains packaged functions (COMDATs) if it has been compiled with the /Gy option. This optimization is called transitive COMDAT elimination. To override this default and keep unreferenced COMDATs in the program, specify /OPT:NOREF. You can use the /INCLUDE option to override the removal of a specific symbol.




Place each function or data item into its own section in the output file if the target supports arbitrary sections. The name of the function or the name of the data item determines the section’s name in the output file.

Use these options on systems where the linker can perform optimizations to improve locality of reference in the instruction space. Most systems using the ELF object format and SPARC processors running Solaris 2 have linkers with such optimizations. AIX may have these optimizations in the future.

Only use these options when there are significant benefits from doing so. When you specify these options, the assembler and linker will create larger object and executable files and will also be slower. You will not be able to use “gprof” on all systems if you specify this option and you may have problems with debugging if you specify both this option and -g.



Enable garbage collection of unused input sections. It is ignored on targets that do not support this option. This option is not compatible with -r or –emit-relocs. The default behaviour (of not performing this garbage collection) can be restored by specifying –no-gc-sections on the command line.

转载注明原文:c++ 为什么可执行文件这么大? (为什么没有删除死代码?) - 代码日志