为什么局部常量变量不会转到.rodata部分?

时间:2013-02-27 06:09:30

标签: c compiler-construction const elf

#include <stdio.h>

void inc(int* p) {
        *p = *p + 1;
}

int main() {
        const int a = 10;
        inc(&a);
        printf("%d\n",a);
}

上面的程序编译没有任何错误,输出为11,因为局部变量'a'进入堆栈。

所以我的问题是:

  1. 为什么'a'进入堆叠。我期待它进入.rodata部分。但为什么不呢?
  2. 如果我将'a'声明为全局常量变量,它会进入.rodata部分。
  3. 这让我很开心!!

3 个答案:

答案 0 :(得分:3)

除了名称之外,const不会在C中声明常量,而是在不可修改的变量中。 必须在&#34;堆栈上实现它&#34;因为函数的递归调用必须导致该变量的不同实例化。 (这些可以通过他们的地址来区分。)在你的情况下,你的函数并没有导致可能的优化,但是这个优化路径不一定要被采用。

至于违反const属性,每个编译器都必须给你一个&#34;诊断&#34;这是你自己的风险。

答案 1 :(得分:1)

允许编译器做任何想做的事情。如果您声明它static,您可能会得到您正在寻找的行为。

在这种特定情况下,您通过尝试修改const值导致未定义的行为,因此确实所有投注均已关闭。

例如,我刚刚使用clang构建了您的确切程序,并获得10的输出。它确实发出了关于丢弃const限定符的警告:

example.c:9:13: warning: passing 'const int *' to parameter of type 'int *' discards qualifiers [-Wincompatible-pointer-types]
        inc(&a);
            ^~
example.c:3:15: note: passing argument to parameter 'p' here
void inc(int* p) {
              ^
1 warning generated.

答案 2 :(得分:0)

在C中,“常量变量”实际上是承诺不会改变的变量,仅此而已。如果它是函数的局部函数,则会像任何其他变量一样创建,初始化并随后销毁它。唯一不同的是,如果你(公然)尝试改变它,你会尖叫。即:

const int a = 15;
...
a = 17;  /* error: assignment of read-only variable ‘a’ */
...
int *p = (int *) &a;
...
*p = 117; /* Just fine, will even work making a == 117 */