コンパイラー(GCCなど)は、const
変数とstatic const
変数をどのように割り当てますか?データメモリまたはプログラムメモリ?
これは、システム、および変数の使用方法によって異なります。 static
変数の場合:
ケース1:変数を使用することはなく、コンパイラは暗黙的にその変数を破棄します。これは、extern
変数では発生しません。
ケース2:変数を使用しますが、そのアドレスを取得することはありません。コンパイラーは、#define
またはenum
であるかのように、変数の使用を即値オペランドに変換します。コンパイラはextern
staticを即値オペランドに変換できますが、それでもアドレスを見つける必要があります。
ケース3:変数を使用してそのアドレスを取得すると、extern
とまったく同じように、コンパイラーはオブジェクトコードに変数を配置する場所を強制的に求めます。
「データ」メモリと「プログラム」メモリについては、使用しているシステムによって異なります。 Linux x64/ELFシステムでは、コードと同じセグメント(.rodata
)に入る.text
セクションに配置されますが、読み取り/書き込みデータセクション(.bss
、.data
)。私のシステムは、読み取り専用の非実行可能データ用に別のセグメントを作成していないようです。
補遺: C++では動作が異なることに注意してください。 C++では、const
変数にはデフォルトで内部リンケージがあるため、static const
は冗長であり、外部リンケージで定数を取得するにはextern const
が必要です。
ディートリッヒはすでにstatic
変数の場合についてよく説明しています。
ローカル変数の場合、コンパイラーの実装には、アドレスが取得されるconst
修飾変数をどこに割り当てるかについていくつかの選択肢があります。スタックまたは静的メモリに割り当てられる場合とされない場合があります。これは特にconst
修飾複合リテラルの場合です。異なるスコープでローカルに宣言されているそのような2つのリテラルのアドレスは1つに折りたたまれ、それらのアドレスは比較されることがあります。