“static const”、“#define”和“enum”在性能和内存使用方面有何区别?

4

由于#define语句的内联,可能会出现任何问题。

我知道答案可能与编译器有关,我们假设是GCC。

已经有类似的问题关于C关于C++,但它们更多地涉及使用方面。


请给出您所询问的值的示例。由于您提到了“枚举”和整数数字常量,我猜想您是在询问这些类型的值? - πάντα ῥεῖ
@πάνταῥεῖ 我是在一般情况下询问 - 关于所有可能的常量类型:数字,字符串字面值,数组... - user
3
因此,重要的信息是在“现代”C++中不要使用#define来定义整数常量。如果它确实是一个数字,请使用static const;如果它确实是可枚举值,请使用枚举。不要担心性能和内存使用:相信你的编译器,除非它真的非常关键,在这种情况下请相信你的编译器,但务必进行检查。 - Dale Wilson
2个回答

6
编译器在基本优化下会将它们视为相同。检查起来相当容易 - 考虑以下C代码:
#define a 1
static const int b = 2;
typedef enum {FOUR = 4} enum_t;

int main() {

    enum_t c = FOUR;

    printf("%d\n",a);
    printf("%d\n",b);
    printf("%d\n",c);

    return 0;
}

使用gcc -O3编译:

0000000000400410 <main>:
  400410:       48 83 ec 08             sub    $0x8,%rsp
  400414:       be 01 00 00 00          mov    $0x1,%esi
  400419:       bf 2c 06 40 00          mov    $0x40062c,%edi
  40041e:       31 c0                   xor    %eax,%eax
  400420:       e8 cb ff ff ff          callq  4003f0 <printf@plt>
  400425:       be 02 00 00 00          mov    $0x2,%esi
  40042a:       bf 2c 06 40 00          mov    $0x40062c,%edi
  40042f:       31 c0                   xor    %eax,%eax
  400431:       e8 ba ff ff ff          callq  4003f0 <printf@plt>
  400436:       be 04 00 00 00          mov    $0x4,%esi
  40043b:       bf 2c 06 40 00          mov    $0x40062c,%edi
  400440:       31 c0                   xor    %eax,%eax
  400442:       e8 a9 ff ff ff          callq  4003f0 <printf@plt>

完全相同的汇编代码,因此 - 具有完全相同的性能和内存使用情况。

编辑:如达蒙在评论中所述,可能存在一些边角案例,例如复杂的非文字常量,但这超出了问题范围。


3
有趣的大小写选择:一个小写字母的宏和一个全大写字母的枚举 :) - David Rodríguez - dribeas
谢谢回答,但是如果这些常量有多个用途,汇编表示会不会改变? - user
1
@user3075942:会有更多的代码,但如果你只使用value,编译器将在调用的地方替换它。为什么变量的1或100个使用会改变呢? - David Rodríguez - dribeas
1
关于字符串字面量 - 与“枚举”比较更加复杂,但这并不改变根本的事实 - 编译器将所有这些都视为值,并且可以优化您可能认为它们保存的任何类型的临时存储。因此,对于编译器来说,处理一种常量与另一种常量没有任何区别(更不用说编译器甚至看不到“#define”)。 - Leeor
3
不幸的是,“相同”在许多非整型字面量情况下并不成立。例如,您可能希望 static const& 也可以被轻松地进行优化,但实际上并不是这样。例如,struct foo {int bar;}; static const& bar_ref = foo.bar; 明显比 #define bar_ref foo.bar 更具开销。(是的,实际上有一些需要使用这种丑陋写法的情况,别问为什么。) - Damon
显示剩余5条评论

3

当作为常量表达式使用时,性能没有区别。如果作为lvalue使用,static const将需要被定义(内存)和访问(CPU)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接