2016-08-12 7 views
8

のstatic constの変数宣言私はこのようなヘッダファイルで静的定数変数を宣言する場合:ヘッダファイル

static const int my_variable = 1; 

、その後、複数の.cファイルにこのヘッダーを含め、各ファイルごとに新しいインスタンスを作るcompilatorますそれが「const」であることを確認するのに十分なほどスマートになり、すべてのファイルに対して1つのインスタンスしか作成されませんか?

私はそれをエクスターナルにして、それを.cのファイルに定義することができますが、これは私がやりたくないことです。

+0

残念なことに、Cの任意の型の名前付き定数はありません。あなたの場合は、列挙型で取り除くことができます。 'enum {my_value = 1、};'これはCで 'int'型の列挙型定数を必要とするでしょう。あなたはそのような獣のアドレスを取ることができません。 –

答えて

9

私はこれを長さhereで回答しました。その答えはC++のものですが、Cでも同様です。

翻訳単位は個々のソースファイルです。ヘッダーを含む各翻訳単位にはstatic const intが表示されます。この文脈でstaticは、my_variableの範囲が翻訳単位に限定されていることを意味します。したがって、それぞれの翻訳単位(.cファイル)には、と別々のmy_variableとなります。コンパイラは、すべてのファイル1つだけのインスタンスを作成する「スマート」ではないでしょう

明示的は(static)そうしていないことを告げので、それは、故障しだろう。

+1

'extern'バージョンは、値を他のTUに見せられないという不幸な性質を持っています。 –

+0

@ JensGustedt:実行時に可視ではなく、コンパイル時に可視であることを意味します( 'extern'変数は確かにそうです)。それは正しいです。そのサイドノートを削除しました。 – DevSolar

+0

@DevSolarコンパイラに強制的に1つのインスタンスを作成させる方法があるかどうかは分かりますか? GCCには、私の例のようにconst変数をコンパイラと比較し、それらを1つにマージするオプションがありますが、それを見つけることはできませんでした。 –

-1

すべてのファイルに対して1つのインスタンスしか作成されないと思います。しかし、異なるファイルで呼び出してその値を確認することで検証できます。

+4

一部のコンパイラでの推測とテストでは、標準が規定していることは分かりません。 –

3

このオブジェクトのアドレスを使用する場合、コンパイラは必ず各翻訳単位ごとに1つのインスタンスを作成します。値のみを使用する場合は、オブジェクトの作成を避けるほどスマートです(必要な場合は値がインライン展開されます)。

+0

私はあなたには分かりませんが、オブジェクトのアドレスと値の両方が、 'static'キーワードのためにユニットの外部にアクセスできませんか? –

+0

@AlterMannはい、もちろんスコープは 'static'によって制限されていますが、その変数のアドレスを表示したい、または何らかのアドレス演算(配列ではないので奇妙なことです)をしたい - コンパイラはそれを静かに最適化してインライン化することができず、そのための記憶域を割り当てる必要があります。 – Sergio

+0

ああ、ああ、そのオブジェクトのアドレスを使用すると、混乱してしまいました。変数のアドレスとして '&my_variable'を考えていました。 –

関連する問題