一、const 作用于局部变量:(包括函数参数)
作用于局部变量的const 关键字是用来进行编译器的检查,该局部变量初识化,直接修改该变量在编译器期间引发错误,但可以通过其他手段,操作。
而对只读数据段.rodata中数据进行操作,将在运行时引发段错误(如修改常量字符串。)。因为.rodata数据段受到MMU的保护。
[wzb@embedded ~]$ cat testConst.c
#include <stdio.h>
int main(int argc, char * argv[]) {
const int n = 0;
const char s[6] = "Hello";
char *str = "Hello";
int * ptr = &n;
(*ptr)++;
printf("%d\n", n);
char * sptr = s;
sptr[0] = 'h';
printf("%s\n", s);
str[0] = 'h';
printf("%s\n", str);
return 0;
}
[wzb@embedded ~]$ gcc testConst.c -o testConst
testConst.c: In function ‘main’:
testConst.c:9: 警告:初始化丢弃了指针目标类型的限定
testConst.c:13: 警告:初始化丢弃了指针目标类型的限定
[wzb@embedded ~]$ ./testConst
1
hello
段错误
[wzb@embedded ~]$
可见,局部变量只进行类型检查。
二、对于const修饰的全局变量
对于全局变量, 确实分配到.rodata数据段,对其修改将引发段错误。
[wzb@embedded ~]$ cat testConst1.c
#include <stdio.h>
const int n = 0;
const char s[6] = "Hello";
char *str = "Hello";
int main(int argc, char * argv[]) {
int * ptr = &n;
(*ptr)++;
printf("%d\n", n);
char * sptr = s;
sptr[0] = 'h';
printf("%s\n", s);
str[0] = 'h';
printf("%s\n", str);
return 0;
}
[wzb@embedded ~]$ gcc testConst1.c
testConst1.c: In function ‘main’:
testConst1.c:9: 警告:初始化丢弃了指针目标类型的限定
testConst1.c:13: 警告:初始化丢弃了指针目标类型的限定
[wzb@embedded ~]$ ./a.out
段错误
[wzb@embedded ~]$
因为,只读数据段 .rodata 是受MMU存储管理单元保护,因此能够产生段错误。
三、 总之, 局部的const变量用于对类型的检查,而全局的const变量分配到只读数据段.rodata,而且受MMU的保护。不可一概而论.