グローバル変数の使い方
結論から言えば、使用する場所の1つで定義
をして、ヘッダーファイルで宣言
するのが良いようです。
グローバル変数の規則
- 規則1 同名の strong symbol が複数存在してはならない。
- 規則2 同名の strong symbol と weak symbol が存在する場合、strong symbol を選ぶ。
- 規則3 同名の weak symbol が複数存在する場合は、任意の1つを選ぶ。
symbol のタイプ
この記事の範囲ではシンボルはグローバル変数のことだと考えても大丈夫です。
symbol のタイプ | 詳細 |
---|---|
strong symbol | 関数および、初期化済みグローバル変数 => 定義 ( defined ) |
weak symbol | 初期化されていないグローバル変数 => 宣言 ( declared ) |
これは、ストレージが割当られているかで判断されています。
グローバル変数の使い方
他の場所でstrong symbolとして定義
されると意図しない値が設定されてしまう危険性があるため、使用したい場所で定義
して、ヘッダーでexternで宣言
しておきます。
ヘッダーでexternを使用する意義としては、明示的に宣言
のみすることができるためです。予め定義
を別ファイルで行っているため、規則3が適応されて定義
が意図しない場所で起こることを防ぐことができます。
コードによる具体例
foo.c
/* foo.c */
# include <stdio.h>
# include "foo.h"
int x = 100;
int main()
{
printf("x = %d\n", x);
f();
printf("x = %d\n", x);
return 0;
}
bar.c
/* bar.c */
# include "foo.h"
void f()
{
x = 200;
}
foo.h
/* foo.h */
extern int x;
void f(void);
出力結果
$ gcc foo.c bar.c && ./a.out
x = 100
x = 200
参考
コンピュータ・システム 第七章
記憶域クラス指定子 - cppreference.com
c - How do I use extern to share variables between source files? - Stack Overflow