gpt4 book ai didi

c++ - C++ 中的 static const 与 #define - 可执行文件大小的差异

转载 作者:可可西里 更新时间:2023-11-01 16:50:47 25 4
gpt4 key购买 nike

我的基本情况:我有一个包含类似#define foo (Flag1 | Flags2 | Flag3) 的包含文件,因此它是位标志的预定义组合。为了类型安全,我想用静态常量替换这些#defines,即 static const int foo = (Flag1 | Flag2 | Flag3) (或类似的)。这个包含文件包含在程序的几十个地方。

现在,当我在启用所有相关优化选项(使用 VS2010 的 C++ 编译器)的情况下进行发布构建时,替换 #defines 似乎会使可执行文件增加几个 KiB,具体取决于我替换了多少常量。

为什么会这样?据我所知,如果可能的话,整数常量应该“内联”到生成的 ASM 代码中,我看不出如何使用 static const vs #define 会有所作为。显然,如反汇编所示,该变量并未内联:

#define:
01325041 or eax,0FFD87FE0h
static int:
011E5451 or eax,dword ptr [CMainFrame::s_TemplateModulePaths+38h (151F008h)]

所以最后一个问题是:如何避免 #define 但仍然依赖于直接插入到生成的程序集中的变量?

最佳答案

编译器没有理由不能消除静态常量变量。如果您在启用优化的情况下进行编译,我很惊讶 VC++ 不会这样做。

我尝试用 gcc 编译这段代码。

enum { FLAG1 = 1 << 0, FLAG2 = 1 << 1, FLAG3 = 1 << 2 };

static const int foo = (FLAG1 | FLAG2 | FLAG3);

int main(){
return foo;
}

关闭优化后,它会内联值但仍为变量保留存储空间。

_main:
LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
call ___main
movl $7, %eax ;value inlined
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE0:
.section .rdata,"dr"
.align 4
__ZL3foo: ; storage space for foo
.long 7

在 O2,它内联了值并摆脱了存储空间。

_main:
LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
call ___main
movl $7, %eax ; value inlined
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE0:
; no storage space for foo

除了不正确的编译器设置或 VC++ 未能进行此优化之外,我唯一想到的是 Flags 变量可能不是编译时常量,这意味着必须在程序启动时计算表达式的值,这会阻止内联。

关于c++ - C++ 中的 static const 与 #define - 可执行文件大小的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11779361/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com