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
Tags: .
你好!除了代码,此处没有多少原创之物,皆为本人搜集、整理、总结之记录与心得,欢迎转载分享!转载时请尽量注明出处,将不胜感激。祝你健康、快乐!
Home

RFC: Request For Comments. Orz..

Name(required)
Mail (required),(will not be published)

RFC: Request For Comments. Orz..

Website(recommended)