Looking for c Answers? Try Ask4KnowledgeBase
Looking for c Keywords? Try Ask4Keywords

C Languageストレージクラス


前書き

記憶域クラスは、変数または関数のスコープを設定するために使用されます。変数のストレージクラスを知ることで、プログラムの実行時にその変数の存続時間を判断できます。

構文

  • [auto | register | static | extern] <データ型> <変数名> [= <値>];

  • [静的_Thread_local | extern _Thread_local | _Thread_local] <データ型> <変数名> [= <値>]; / *>以降= C11 * /

  • 例:

  • typedef int foo ;

  • extern int foo [2];

備考

ストレージクラス指定子は、宣言のトップレベル型の隣に表示されるキーワードです。これらのキーワードを使用すると、ファイルスコープで宣言されているかブロックスコープで宣言されているかによって、宣言されたオブジェクトの格納期間とリンケージに影響します。

キーワード保管期間リンケージ備考
static 静的内部ファイルスコープのオブジェクトの内部リンケージを設定します。ブロックスコープのオブジェクトの静的記憶期間を設定します。
extern 静的外部したがって、初期化子を持つファイルスコープで定義されたオブジェクトには暗黙のため、重複しています。イニシャライザなしでファイルスコープの宣言で使用される場合、その定義が別の変換単位で検出され、リンク時に解決されることを暗示します。
auto 自動無関係ブロックスコープで宣言されたオブジェクトには暗示され、したがって冗長性があります。
register 自動無関係自動保存期間を持つオブジェクトにのみ関連します。変数がレジスタに格納されるべきであるというヒントを提供します。課される制約は1つが単項使用できないことがある& 、そのような物体上のオペレータ「のアドレス」、したがってオブジェクトがエイリアスすることができません。
typedef 無関係無関係実際にはストレージクラス指定子ではありませんが、構文的な観点からは同じように動作します。唯一の違いは、宣言された識別子がオブジェクトではなく型であることです。
_Thread_local 内部/外部 C11で導入され、 スレッド記憶期間を表します 。ブロックスコープで使用される場合は、 externまたはstaticも含みstatic

これらのキーワードが省略されている場合でも、すべてのオブジェクトには関連する保存期間(スコープに関係なく)とリンケージ(ファイルスコープでの宣言にのみ関連する)があります。

トップレベル型指定子( intunsignedshortなど)およびトップレベル型修飾子( constvolatile )に対するストレージクラス指定子の順序は強制されないため、これらの宣言は両方とも有効です。

int static const unsigned a = 5; /* bad practice */
static const unsigned int b = 5; /* good practice */

しかし、最初に記憶域クラス指定子を置いてから型修飾子を指定し、型指定子( voidcharintsigned longunsigned long longlong double ...)を置くことをおcharます。

すべてのストレージクラス指定子が特定のスコープで合法であるとは限りません。

register int x; /* legal at block scope, illegal at file scope */
auto int y; /* same */

static int z; /* legal at both file and block scope */
extern int a; /* same */

extern int b = 5; /* legal and redundant at file scope, illegal at block scope */

/* legal because typedef is treated like a storage class specifier syntactically */
int typedef new_type_name;

保管期間

保存期間は静的または自動のいずれかです。宣言されたオブジェクトの場合、そのスコープとストレージクラス指定子によって決定されます。

静的ストレージ期間

静的な記憶期間を持つ変数は、プログラムの実行全体を通して生きており、ファイルスコープ( staticまたは無し)とブロックスコープ(明示的にstaticに置く)の両方で宣言することができます。これらは通常、プログラムの起動時にオペレーティングシステムによって割り当てられ、初期化され、プロセスが終了すると再利用されます。実際には、実行形式にはそのような変数( databss 、およびrodata )の専用セクションがあり、ファイルのこれらのセクション全体が特定の範囲でメモリにマップされます。

スレッドの保存期間

C11

この保管期間はC11で導入されました。これは以前のC標準では利用できませんでした。コンパイラの中には、同様のセマンティクスを持つ非標準拡張を提供するものがあります。例えば、gccがサポート__thread持っていなかった以前のC規格で使用可能な指定_Thread_local

スレッド記憶期間を持つ変数は、ファイルスコープとブロックスコープの両方で宣言できます。ブロックスコープで宣言されている場合は、 staticまたはexternストレージ指定子も使用します。その存続期間は、それが作成されたスレッドの実行全体です。これは、別のストレージ指定子と一緒に使用できる唯一のストレージ指定子です。

自動保存期間

自動保存期間を持つ変数は、ブロックスコープで(関数内またはその関数内のブロック内で直接)宣言することができます。これらは、ファンクションまたはブロックの入力から終了までの間にのみ使用できます。変数がスコープから外れると(関数から戻るかブロックを離れることによって)、そのストレージは自動的に割り当てが解除されます。ポインタからの同じ変数へのそれ以上の参照は無効であり、未定義の動作につながります。

典型的な実装では、自動変数は、関数のスタックフレームまたはレジスタ内の特定のオフセットに配置されます。

外部リンクと内部リンク

リンケージはファイルスコープで宣言されたオブジェクト(関数と変数)にのみ関連し、異なる翻訳単位間の可視性に影響します。外部リンケージを持つオブジェクトは、他のすべての翻訳単位で表示されます(適切な宣言が含まれている場合)。内部リンケージを持つオブジェクトは他の翻訳単位には公開されず、定義されている翻訳単位でのみ使用できます。

ストレージクラス 関連する例