2
#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 部分。

这让我很开心!!

4

3 回答 3

3

除了名称表示const不在 C 中声明常量,而是在不可修改的变量中声明。它必须在“堆栈”上实现它,因为函数的递归调用必须导致该变量的不同实例化。(这些可以通过它们的地址来区分。)在您的情况下,您的函数不会递归导致可能的优化,但不一定要采用这种优化路径。

至于违反const属性,每个编译器都必须给你一个“诊断”,这是你自己承担的风险。

于 2013-02-27T07:07:58.600 回答
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.
于 2013-02-27T06:12:35.777 回答
0

在 C 中,“常量变量”实际上是承诺不会更改的变量,仅此而已。如果它是函数的局部变量,则它会像任何其他变量一样被创建、初始化和销毁​​。唯一不同的是,如果你(公开地)试图改变它,你会被吓到。IE:

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 */
于 2013-02-27T18:01:11.790 回答