前两天跟“专家”讨论const能不能强制类型转换的问题,像专家这样的内存使用高手,基本上不在乎什么const不const,拿来就用,强转一下就行,事实证明确实强转成非const,毫无压力,不过我一直觉得有问题,所以今天自己做了个实验,证实了一下。
程序非常的简单,写一个这样的函数:
void foo(const char *p)
{
const char *a = "foo";
printf("%p\n%p\n", p, a);
}
打印一下结果,可以发现两个地址明显不同,当然,前提是我们在调用函数的时候,给一个普通的char*,而不是const char*。这样,在函数里,我们可以强转p,而不能强转a。(编译不会报错,运行就崩)
在Linux中,a的地址明显是一个低地址,而p是一个高地址,根据一般的装载原则,代码段一般会放在低地址,而数据段一般会放在高地址,所以我们可以猜想“foo”这个字符串是和代码放在了一起,而p是和数据放在了一起。了解过32位保护模式的同学应该会知道,在32位虚地址环境下,地址在转换的过程中,是有“只读”标记控制的,代码段显然是“只读”的,而数据段是“可写”的,所以,我们可以正常的方位foo,但是却不能修改它,一切的修改动作都会被操作系统截获,然后抛出“段错误”。
所以,我们今后在使用const强转的时候,其实更应该关心的是我们究竟使用的是哪块内存,做到这一点,就可以各种强转无压力了……