一、const常量分析
1、
#include <stdio.h>
const bufsize = 100;
char buf[bufsize];
int main()
{
return 0;
}
编译:gcc -c test.c
报错:test.c:3: error: variably modified 'buf’ at file scope
2、把buf定义到main函数中
#include <stdio.h>
const bufsize = 100;
int main()
{
char buf[bufsize];
return 0;
}
编译:gcc -c test.c 通过
查看二进制文件:objdump -s test.o
Contents of section .text:
0000 8d4c2404 83e4f0ff 71fc5589 e5575653 .L$.....q.U..WVS
0010 5183ec38 65a11400 00008945 e431c089 Q..8e......E.1..
0020 e08945d4 a1000000 0083e801 8945e0a1 ..E..........E..
0030 00000000 ba000000 0089c180 e5ff89d3 ................
0040 83e30f89 c889da0f a4c203c1 e00389c6 ................
0050 83e6ff89 d783e70f 89f089fa a1000000 ................
0060 00ba0000 000089c1 80e5ff89 4dc889d1 ............M...
0070 83e10f89 4dcc8b45 c88b55cc 0fa4c203 ....M..E..U.....
0080 c1e00389 c180e5ff 894dc089 d183e10f .........M......
0090 894dc48b 45c08b55 c4a10000 000083c0 .M..E..U........
00a0 0f83c00f c1e804c1 e00429c4 89e083c0 ..........).....
00b0 0fc1e804 c1e00489 45dcb800 0000008b ........E.......
00c0 65d48b55 e4653315 14000000 7405e8fc e..U.e3.....t...
00d0 ffffff8d 65f083c4 00595b5e 5f5d8d61 ....e....Y[^_].a
00e0 fcc3 ..
Contents of section .rodata:
0000 64000000 d...
Contents of section .comment:
0000 00474343 3a202855 62756e74 7520342e .GCC: (Ubuntu 4.
0010 342e332d 34756275 6e747535 2e312920 4.3-4ubuntu5.1)
0020 342e342e 3300 4.4.3.
从输出可以看出:全局定义的const常量是要占用内存的
3、都在main中定义
#include <stdio.h>
int main()
{
const bufsize = 100;
char buf[bufsize];
return 0;
}
编译:gcc -c test.c 通过
查看二进制文件:objdump -s test.o
Contents of section .text:
0000 8d4c2404 83e4f0ff 71fc5589 e5575653 .L$.....q.U..WVS
0010 5183ec38 65a11400 00008945 e431c089 Q..8e......E.1..
0020 e08945d4 c745e064 0000008b 45e083e8 ..E..E.d....E...
0030 018945dc 8b45e0ba 00000000 89c180e5 ..E..E..........
0040 ff89d383 e30f89c8 89da0fa4 c203c1e0 ................
0050 0389c683 e6ff89d7 83e70f89 f089fa8b ................
0060 45e0ba00 00000089 c180e5ff 894dc889 E............M..
0070 d183e10f 894dcc8b 45c88b55 cc0fa4c2 .....M..E..U....
0080 03c1e003 89c180e5 ff894dc0 89d183e1 ..........M.....
0090 0f894dc4 8b45c08b 55c48b45 e083c00f ..M..E..U..E....
00a0 83c00fc1 e804c1e0 0429c489 e083c00f .........)......
00b0 c1e804c1 e0048945 d8b80000 00008b65 .......E.......e
00c0 d48b55e4 65331514 00000074 05e8fcff ..U.e3.....t....
00d0 ffff8d65 f083c400 595b5e5f 5d8d61fc ...e....Y[^_].a.
00e0 c3 .
Contents of section .comment:
0000 00474343 3a202855 62756e74 7520342e .GCC: (Ubuntu 4.
0010 342e332d 34756275 6e747535 2e312920 4.3-4ubuntu5.1)
0020 342e342e 3300 4.4.3.
注意:在main中定义的const常量是不占内存的
二、const变量
1、
#include <stdio.h>
const int bufsize = 100;
char buf[bufsize];
int main()
{
return 0;
}
和一、1中const常量同样的问题:test.c:3: error: variably modified 'buf’ at file scope
2、
#include <stdio.h>
const int bufsize = 100;
int main()
{
char buf[bufsize];
return 0;
}
Contents of section .text:
0000 8d4c2404 83e4f0ff 71fc5589 e5575653 .L$.....q.U..WVS
0010 5183ec38 65a11400 00008945 e431c089 Q..8e......E.1..
0020 e08945d4 a1000000 0083e801 8945e0a1 ..E..........E..
0030 00000000 ba000000 0089c180 e5ff89d3 ................
0040 83e30f89 c889da0f a4c203c1 e00389c6 ................
0050 83e6ff89 d783e70f 89f089fa a1000000 ................
0060 00ba0000 000089c1 80e5ff89 4dc889d1 ............M...
0070 83e10f89 4dcc8b45 c88b55cc 0fa4c203 ....M..E..U.....
0080 c1e00389 c180e5ff 894dc089 d183e10f .........M......
0090 894dc48b 45c08b55 c4a10000 000083c0 .M..E..U........
00a0 0f83c00f c1e804c1 e00429c4 89e083c0 ..........).....
00b0 0fc1e804 c1e00489 45dcb800 0000008b ........E.......
00c0 65d48b55 e4653315 14000000 7405e8fc e..U.e3.....t...
00d0 ffffff8d 65f083c4 00595b5e 5f5d8d61 ....e....Y[^_].a
00e0 fcc3 ..
Contents of section .rodata:
0000 64000000 d...
注意:和const常量一样,全局定义的const变量是要占用内存的
3、
#include <stdio.h>
int main()
{
const int bufsize = 100;
char buf[bufsize];
return 0;
}
注意:和const常量一样,在main中定义的const变量是不占内存的
总结:
a、全局定义的const常量和const变量链接的时候都要占用内存,且存放在只读数据段(.rodata)
b、局部定义的const常量和const变量链接的时候都不占内存,运行的时候在栈上分配空间。
const常量和#define常量比较:
a、const常量有数据类型,而宏常量没有数据类型;
b、有些集成化的调试环境工具可以对const常量进行调试,但不能对宏常量进行调试。
在C++中:编译器会为常量分配了地址,但是在使用常量的时候,常量会被一立即数替换(保护常量,防止被破坏性修改)
在C++中对于基本类型的常量,编绎器并不为其分配存储空间,编译器会把它放到符号表,当取符号常量的地址等操作时,将强迫编译器为这些常量分配存储空间,编译器会重新在内存中创建一个它的拷贝,通过地址访问到的就是这个拷贝而非原始的符号常量。
而在C语言中没有常量折叠。