web-dev-qa-db-ja.com

定数と静的定数

コンパイラー(GCCなど)は、const変数とstatic const変数をどのように割り当てますか?データメモリまたはプログラムメモリ?

43
freonix

これは、システム、および変数の使用方法によって異なります。 static変数の場合:

ケース1:変数を使用することはなく、コンパイラは暗黙的にその変数を破棄します。これは、extern変数では発生しません。

ケース2:変数を使用しますが、そのアドレスを取得することはありません。コンパイラーは、#defineまたはenumであるかのように、変数の使用を即値オペランドに変換します。コンパイラはextern staticを即値オペランドに変換できますが、それでもアドレスを見つける必要があります。

ケース3:変数を使用してそのアドレスを取得すると、externとまったく同じように、コンパイラーはオブジェクトコードに変数を配置する場所を強制的に求めます。

「データ」メモリと「プログラム」メモリについては、使用しているシステムによって異なります。 Linux x64/ELFシステムでは、コードと同じセグメント(.rodata)に入る.textセクションに配置されますが、読み取り/書き込みデータセクション(.bss.data)。私のシステムは、読み取り専用の非実行可能データ用に別のセグメントを作成していないようです。

補遺: C++では動作が異なることに注意してください。 C++では、const変数にはデフォルトで内部リンケージがあるため、static constは冗長であり、外部リンケージで定数を取得するにはextern constが必要です。

40
Dietrich Epp

ディートリッヒはすでにstatic変数の場合についてよく説明しています。

ローカル変数の場合、コンパイラーの実装には、アドレスが取得されるconst修飾変数をどこに割り当てるかについていくつかの選択肢があります。スタックまたは静的メモリに割り当てられる場合とされない場合があります。これは特にconst修飾複合リテラルの場合です。異なるスコープでローカルに宣言されているそのような2つのリテラルのアドレスは1つに折りたたまれ、それらのアドレスは比較されることがあります。

5
Jens Gustedt