2
#include <stdio.h>

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

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

上記のプログラムはエラーなしでコンパイルされ、ローカル変数 'a' がスタックに入るため、出力は 11 になります。

だから私の質問は:

  1. 「a」がスタックに入る理由。.rodata セクションに入ると思っていました。しかし、なぜそうしなかったのですか?
  2. 一方、「a」をグローバル定数変数として宣言すると、.rodata セクションに入ります。

これは私を楽しませます!!

4

3 に答える 3

3

名前が示す以外はconst、C で定数を宣言していませんが、変更できない変数です。関数の再帰呼び出しはその変数の異なるインスタンス化につながる必要があるため、「スタック」でそれを実現する必要があります。(これらはアドレスによって区別できます。)ここで関数が再帰しない場合、最適化の可能性につながりますが、この最適化パスを必ずしも採用する必要はありません。

プロパティの違反に関してはconst、すべてのコンパイラは、これが自己責任であるという「診断」を提供する必要があります。

于 2013-02-27T07:07:58.600 に答える
1

コンパイラは、やりたいことを何でもすることができます。宣言するとstatic、探している動作が得られる場合があります。

constこの特定のケースでは、値を変更しようとして未定義の動作を引き起こしているため、実際にはすべての賭けがオフになっています。

たとえば、ここであなたの正確なプログラムをclangでビルドしたところ、の出力が得られます10const修飾子の破棄に関する警告が表示されました。

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 では、「定数変数」は実際には変更しないこと約束する変数であり、それ以上のものではありません。関数に対してローカルである場合は、他の変数と同様に、作成、初期化、および後で破棄されます。唯一の違いは、(あからさまに) 変更しようとすると怒られることです。すなわち:

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 に答える