Effective C++第三版中文版(候捷译)第二条“尽量以const, enum, inline 替换#define”中讲到 此外虽然优秀的编译器不会为“整数型const对象”设定另外的内存空间(除非你创建一个pointer或reference指向该对象),不够优秀的编译器却可能如此,而这可能是你不想要的。Enum和#defeine一样绝不会导致非必要的内存分配。
于是验证了一下,环境是Fedora9,gcc4.3。
代码一:
#include <stdio.h>
int NotAConst = 10;
const int MonthsInYear = 12;
const int AverDaysInMonth = 30;
const float PI = 3.1415;
int main()
{
const int *p;
p = &AverDaysInMonth;
printf("%d, %d, %f/n", MonthsInYear, AverDaysInMonth, PI);
printf("address of AverDaysInMonth is %d", p);
printf("%d %d %f/n", MonthsInYear, AverDaysInMonth, PI);
return 0;
}
编译命令:gcc -c constVar.c ,然后使用objdump查看生成的二进制文件,objdump -s constVar.o ,显示如下:
constVar.o: file format elf64-x86-64
Contents of section .text:
0000 554889e5 4883ec10 48c745f8 00000000 UH..H...H.E.....
0010 f30f1005 00000000 0f14c00f 5ac08b15 ............Z...
0020 00000000 8b350000 0000bf00 000000b8 .....5..........
0030 01000000 e8000000 00488b75 f8bf0000 .........H.u....
0040 0000b800 000000e8 00000000 f30f1005 ................
0050 00000000 0f14c00f 5ac08b15 00000000 ........Z.......
0060 8b350000 0000bf00 000000b8 01000000 .5..............
0070 e8000000 00b80000 0000c9c3 ............
Contents of section .data:
0000 0a000000 ....
Contents of section .rodata:
0000 0c000000 1e000000 560e4940 25642c20 ........V.I@%d,
0010 25642c20 25660a00 61646472 65737320 %d, %f..address
0020 6f662041 76657244 61797349 6e4d6f6e of AverDaysInMon
0030 74682069 73202564 00256420 25642025 th is %d.%d %d %
0040 660a00 f..
Contents of section .eh_frame:
0000 14000000 00000000 017a5200 01781001 .........zR..x..
0010 030c0708 90010000 1c000000 1c000000 ................
0020 00000000 7c000000 00410e10 8602430d ....|....A....C.
0030 06000000 00000000 ........
Contents of section .comment:
0000 00474343 3a202847 4e552920 342e332e .GCC: (GNU) 4.3.
0010 30203230 30383034 32382028 52656420 0 20080428 (Red
0020 48617420 342e332e 302d3829 00 Hat 4.3.0-8).
上面0c000000, 1e000000, 560e4940分别是程序中定义的 MonthsInYear, AverDaysInMonth和PI。因此可以看出gcc给const变量都非配了内存空间,不管是否有pointer或者reference指向该变量。因此,以Scott Meyers的标准看,gcc还不是优秀的编译器。
修改一下代码,加入enum:
#include <stdio.h>
int NotAConst = 10;
const int MonthsInYear = 12;
const int AverDaysInMonth = 30;
const float PI = 3.1415;
enum { Num1 = 1, Num2, Num3};
int main()
{
const int *p;
p = &AverDaysInMonth;
printf("%d, %d, %f/n", MonthsInYear, AverDaysInMonth, PI);
printf("address of AverDaysInMonth is %d", p);
printf("%d %d %d/n", Num1, Num2, Num3);
return 0;
}
同样编译并显示二进制文件的内容为:
constVar.o: file format elf64-x86-64
Contents of section .text:
0000 554889e5 4883ec10 48c745f8 00000000 UH..H...H.E.....
0010 f30f1005 00000000 0f14c00f 5ac08b15 ............Z...
0020 00000000 8b350000 0000bf00 000000b8 .....5..........
0030 01000000 e8000000 00488b75 f8bf0000 .........H.u....
0040 0000b800 000000e8 00000000 b9030000 ................
0050 00ba0200 0000be01 000000bf 00000000 ................
0060 b8000000 00e80000 0000b800 000000c9 ................
0070 c3 .
Contents of section .data:
0000 0a000000 ....
Contents of section .rodata:
0000 0c000000 1e000000 560e4940 25642c20 ........V.I@%d,
0010 25642c20 25660a00 61646472 65737320 %d, %f..address
0020 6f662041 76657244 61797349 6e4d6f6e of AverDaysInMon
0030 74682069 73202564 00256420 25642025 th is %d.%d %d %
0040 640a00 d..
Contents of section .eh_frame:
0000 14000000 00000000 017a5200 01781001 .........zR..x..
0010 030c0708 90010000 1c000000 1c000000 ................
0020 00000000 71000000 00410e10 8602430d ....q....A....C.
0030 06000000 00000000 ........
Contents of section .comment:
0000 00474343 3a202847 4e552920 342e332e .GCC: (GNU) 4.3.
0010 30203230 30383034 32382028 52656420 0 20080428 (Red
0020 48617420 342e332e 302d3829 00 Hat 4.3.0-8).
可以看见,加入enum确实没有新分配内存空间。