在函数中声明的const变量的堆栈中是否有只读内存?

时间:2016-05-06 19:41:37

标签: c memory const

我知道全局const存储在.rodata

另外,我知道函数中声明的变量存储在堆栈中。但是因为const应该只是只读的,所以堆栈中是否有特殊的部分?如何控制对它们的访问?

4 个答案:

答案 0 :(得分:4)

你真正应该知道的是:如果一个对象被声明为const,编译器将不会轻易让你尝试修改它,如果你绕过编译器,那么任何修改对象的尝试都是未定义的行为。而已。没有其他的。忘记.rodata或你学到的任何东西,重要的是修改const对象的尝试是未定义的行为。

我的意思是“编译器不会让你”并绕过它:

const int x = 5; 
x = 6; // Not allowed by compiler
int* p = &x; *p = 6; // Not allowed by compiler
int* p = (int*)&x; *p = 6; // Allowed by compiler, undefined behaviour.

执行最后一个语句可能会崩溃,或者将x更改为6,或者将x更改为999,或保持x不变,或使其表现为精神分裂的方式,其中有时为5,其他时间为6,包括x == x是假的。

答案 1 :(得分:1)

const局部变量以恒定的时间点初始化时,它可能根本不存储。请考虑以下代码:

int foo(int param)
{
    const int value = 10;
    return param + value;
}

optimizing compiler很可能会生成汇编代码,例如add操作,其中value10字面值替换。

除此之外,许多编译器会将它们放在堆栈框架上,就像#34;普通"自动变量,因此您可以获得的任何保护都是由编译器本身完成的。

答案 2 :(得分:0)

不,一般来说,没有任何"常数"堆栈的区域。但那没关系,因为const的真正含义是"我保证不会尝试修改这个"。这并不意味着将它放在只读存储器中,这样我们就可以保证在遇到错误时会出现总线错误。

答案 3 :(得分:0)

没有只读堆栈段,因为它必须是可写的初始化,每次进入函数时都会发生。每个函数调用都会产生不合理的开销,要求内核更改页面保护,初始化变量,然后将其更改回来。

rodata起作用,因为静态分配的const变量只初始化一次。