常量int不占用空间吗?

8
这个答案中,Oli Charlesworth在讨论匿名枚举的用法时指出:

const int是不可变的,并且根据编译器选择可能不占用任何空间。

如果我声明const int i = 10,那么如果“可能不占用任何空间”,那么如何存储10
假设一个int占4个字节,我会认为至少需要保留4个字节来存储const int的值10。

3
无论如何都需要空间,问题是在哪里。 - Eric Z
7个回答

10
编译器可以随意优化代码,只要产生的代码具有相同的可观察副作用。因此,变量可能被优化为仅存在于寄存器中,或者替换为立即值。在伪机器代码中:
SET 10, eax
ST eax, &i    # Initialise i

...

LD &i, eax    # Add i to ebx
ADD eax, ebx, ebx

可能会变成:

SET 10, eax
ADD eax, ebx, ebx

或者只需要:

ADD 10, ebx, ebx

我仍然不明白你如何测试这个。是否有编译器文档说明这种优化方式。如果没有,我想知道你是怎么知道编译器能够识别这种优化的。提前致谢。 - atoMerz
@AtoMerZ:一种方法是直接查看编译器的输出(在目标文件或可执行文件上运行objdump或其他工具)。另一种方法是阅读维基百科:http://en.wikipedia.org/wiki/Constant_folding。 - Oliver Charlesworth
再次感谢,链接很有帮助。 - atoMerz

6

除非您使用i的方式需要地址,否则编译器通常只会在编译时使用它,在运行时,剩下的只有10而不是一个变量。

特别地,由于const不会改变,除非您将其传递给以引用参数为参数的函数,否则没有必要实际存储它在内存中。


4

好的,有点误导性地说它不需要空间,因为变量的值实际上仍然会在内存中的指令空间中保留,但是不会分配任何空间来存储所涉及的数据类型。更恰当的说法可能是尽可能少地使用内存,这也是您的反应所指的最小内存量。


3
编译器可能会在每次需要读取时,替换成数字10,而不是读取存储的值。

2

这可能是代码的一部分,作为一个立即值使用(比如#define FIVE 5)。


2
编译器可能会将您代码中所有的i替换为常数10。不再需要i,因此不需要额外的空间,使用魔法数字的成本与之相同(如果编译器没有太蠢或者看到您去掉了const)。这样做可以使代码更易读,对于小的常数,编译器可以将它们折叠到汇编指令中。请保留HTML标签。

0

如果您在全局命名空间中声明它,它很可能会占用空间。 如果您在函数体中声明它,或者在某个地方声明为“静态”,编译器可以自由地删除它。 如果您在全局范围内声明它,则编译器无法知道该常量是否从另一个翻译单元引用。


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