const在C,尤其是C++,是个老生常谈的问题,但这里不谈const具体有哪些特性,如何使用,而是说说const在C和C++中的区别。编译器,C使用gcc,C++使用g++,其它编译器(cl等)请自行验证。
在我的印象中,const就是常量(constant)。但这并不是真的。在C中,const仅仅表示其所修饰对象不可修改。常量和所谓“不可修改”有什么区别呢?C中,const int N = 10; 这样的语句声明了一个整型数据,声明之后你不能再为其赋值,此即为不可修改。但在C中,N却不是常量,而诸如372, 3.72, ‘A’之类才是常量,在C中定义常量通常使用#define。而在C++中,const int N = 10; 就会定义N为常量。
怎么证明呢?你可能知道,定义静态数组,必须使用整型常量指定其大小,那咱们就用这个特性来验证上面描述的观点。
1 2 3 4 5 6 7 | int main(int argc, char **argv) { const int N = 10; int a[N] = { 1, 2, 3 }; return 0; } |
使用g++编译这个程序,没有问题。但若使用gcc,你会得到如下错误信息
main.c: In function ‘main’: main.c:19: error: variable-sized object may not be initialized main.c:19: warning: excess elements in array initializer
但事情并未到此结束,如果你把上面代码中int a[N] = { 1, 2, 3 };的初始化列表去掉,即int a[N]; 然后就也能通过gcc的编译,更有甚者,如果你把const int N = 10;的const去掉:int N = 10; 也能通过gcc的编译!这是gcc所支持的特性,即动态数组。但最好不要这样做,因为gcc会为此生成大量代码。例如,这段代码
1 2 3 4 5 6 7 | int main(int argc, char **argv) { const int N = 10; int a[N]; return 0; } |
使用gcc生成的汇编代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | .file "main.c" .text .globl main .type main, @function main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx) pushl %ebp movl %esp, %ebp pushl %esi pushl %ebx pushl %ecx subl $60, %esp movl %ecx, %eax movl 4(%eax), %eax movl %eax, -44(%ebp) movl %gs:20, %eax movl %eax, -28(%ebp) [ ... ] # 此处略去n行 movl %ecx, %esp movl -28(%ebp), %edx xorl %gs:20, %edx je .L3 call __stack_chk_fail .L3: leal -12(%ebp), %esp addl $0, %esp popl %ecx popl %ebx popl %esi popl %ebp leal -4(%ecx), %esp ret |
整个汇编文件有96行之多。而使用g++(N为常量)编译生成的汇编文件只有23行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | .file "main.c" .text .globl main .type main, @function main: .LFB0: .cfi_startproc .cfi_personality 0x0,__gxx_personality_v0 pushl %ebp .cfi_def_cfa_offset 8 movl %esp, %ebp .cfi_offset 5, -8 .cfi_def_cfa_register 5 subl $48, %esp movl $10, -4(%ebp) movl $0, %eax leave ret .cfi_endproc .LFE0: .size main, .-main .ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3" .section .note.GNU-stack,"",@progbits |
你好!除了代码,此处没有多少原创之物,皆为本人搜集、整理、总结之记录与心得,欢迎转载分享!转载时请尽量注明出处,将不胜感激。祝你健康、快乐!
不知道C/C++标准是怎么定义const的,但是有很多东西是取决于编译器的实现。
我看了一眼标准,这里讨论的内容中,只有动态数组是gcc自身的特性。
支持喽!博客不错!