2

私はいくつかのメモリポインタを扱っています。私はハッシュ定義を使いたくありません。その議論は脇に置いておいてください。これがコンパイルされない理由を知りたいだけです:

#include <stdio.h>

static const unsigned long *const pMemAddrA = (unsigned long *) 0x00000200ul;
static const unsigned long *const pMemAddrB = pMemAddrA;

int main (void)
{
    printf("%x", (unsigned int) pMemAddrB);
    return 0;
}

コンパイラ出力 gcc:

||=== TestConst, Debug ===|
 ...main.c|4|error: initializer element is not constant|
||=== Build finished: 1 errors, 0 warnings ===|

編集:

回答を読んだ後、この問題に対処する方法を知ってうれしく思います。

しかし、なぜそれが問題なのかわかりません。私が知っていることから、プログラムの開始時に静的メモリが割り当てられます。変数が異なるファイルに「存在」し、変数が割り当てられる順序がコンパイラによって保証されない場合、問題があることを私は知っています。ただし、両方の変数が同じファイルに「存在する」場合-同じ関数に両方の変数が存在するのと同じように-ファイルで宣言されている変数の順序でメモリが割り当てられることをコンパイラーが保証できると思います。別の const ポインターへの const ポインターを宣言して初期化することが問題である理由を理解していません。どなたか教えていただけると幸いです。

4

2 に答える 2

2

ポインターにはファイル スコープがあるため、初期化子は定数式でなければなりません。pMemAddrAは定数式ではないため、静的ストレージで変数を初期化するために使用することはできません。

ブロックスコープで変数を初期化するために使用できるため、宣言を内部に移動するmainと(そして少なくとも2番目の非静的にする)、コンパイルされます:

#include <stdio.h>

int main (void)
{

    const unsigned long *const pMemAddrA = (unsigned long *) 0x00000200ul;
    const unsigned long *const pMemAddrB = pMemAddrA;

    printf("%x", (unsigned int) pMemAddrB);
    return 0;
}

2 つのポインターをファイル スコープで宣言する必要がある場合、初期化式の繰り返しを防ぐ方法はありません。

static const unsigned long *const pMemAddrA = (unsigned long *) 0x00000200ul;
static const unsigned long *const pMemAddrB = (unsigned long *) 0x00000200ul;

または#defineそれをする。

于 2012-08-31T14:19:26.630 に答える
2

あなたは「うまくいかない」ことを説明していませんが、その行を意味していると思います

static const unsigned long *const pMemAddrB = pMemAddrA;

エラーが発生します

error: initializer element is not constant

.

解決策は、実際にこの初期化子が定数と見なされないことです。代わりに、 のメモリ領域pMemAddrAが確保され、値0x00000200ulがそこに書き込まれます。それ以降は、定数式ではなく、メモリのどこかにある値です。

それをどうしたいかによっては、次のような別のポインター間接化を追加できます。

static const unsigned long *const * const pMemAddrB = &pMemAddrA;

*pMemAddrBの代わりにアクセスしますpMemAddrB

于 2012-08-31T14:19:36.607 に答える