大阪市中央区 システムソフトウェア開発会社

営業時間:平日09:15〜18:15
MENU

グローバル変数って何?

著者:高木信尚
公開日:2017/12/05
最終更新日:2017/12/04
カテゴリー:技術情報

高木です。こんばんは。

今回は、プログラミングの世界ではとかく嫌われがちな「グローバル変数」について考えてみたいと思います。

「グローバル変数」という用語は、どこからでもアクセスできる変数程度の意味で使われています。
しかし、プログラミング言語によっては、明確に定義されているものもあれば、そうでないものもあります。

そもそも「グローバル」とは何でしょうか?
「変数」とは何でしょうか?
「どこからでも」とは具体的にどういうことでしょうか?
「アクセスできる」とは具体的にどのようなことでしょうか?

とりあえず、具体的なプログラミング言語について考えてみることにしましょう。

まずはPHPからです。

PHPのマニュアルには、「グローバル変数」の記述が何度も登場します。
主に「変数のスコープ」のページで記述を見るけることができます。
PHPの「グローバル変数」とは何かについては、他のページの記述も参照しつつ、私なりに次のように理解しています。

グローバル空間において、関数の外部で定義された変数

PHPのグローバル変数は、関数内ではglobalキーワードを用いて参照することができます。

次にC#です。

C#では、グローバル変数が存在しないことが明確に規定されているようです
クラスや構造体のメンバーは、public staticにすれば他のクラスからだろうが他のアセンブリからだろうがアクセスできるわけですが、これはグローバル変数ではないそうです。

Javaではどうでしょうか?

Javaの言語仕様には、global variable(s)の記述は1箇所しか見つけることができませんでした。
しかも、「shared global variables」という形でです。
これは、スレッド間の共有メモリに関する話で、スコープに関する話ではないように思います。
「どこからでも」アクセスできるという観点からは、どんなスレッドからでもアクセスできる必要があるかもしれませんけど。

グローバル変数がどうのこうのいわれるのは何といってもCを使う場合ですので、Cについても考えてみましょう。

Cの言語規格でも調べてみましたが、global variable(s)が登場するのはC99でもC11でも1箇所だけでした。
「浮動小数点環境のフラグやモードはグローバル変数とみなす」といった内容です。
これは、Cのオブジェクト(普通は「変数」と呼ばれます)ではなく、プロセッサステータスワードや制御レジスタといったハードウェア上のリソースのことです。

また、C11では、浮動小数点環境はスレッド記憶域期間(thread storage duration)を持つことが明記されています。
さっきのJavaの話とはかなりずれてきましたね。

C++についても見ておきましょう。

C++の言語仕様にも、global variable(s)の記述は1箇所だけ見つけることができました。
エラー番号の格納先、つまりerrnoの参照先のことでした。

errnoの具体的な仕様はC規格に振っていますが、これは単なるマクロです。
マクロがどのように展開されるかは当然処理系定義です。
C11では、errnoの参照先はスレッド記憶域間であるとされていますが、C++14が参照しているのは確かC99ですのでこの辺りがあやふやになります。

いくつかの言語を具体的に挙げながら「グローバル変数」がどのように扱われているかを見てきました。
結果、言語によって扱われ方はマチマチで、こんな状況では「グローバル変数」とは一体何なのか、統一的な考え方を導くのは困難です。

多くのコーディング規約ではグローバル変数の使用を禁止、または制限しています。
しかし、「不可能な約束には一人称で対応?」でも書いたように、このようなあいまいなルールを守ることを約束することなどできそうにありません。

C#が主張するように、クラスや構造体のメンバーなら「グローバル変数」ではないのでしょうか?
特定の名前空間で定義した場合はどうなのでしょうか?
スレッドローカルな場合は「グローバル変数」ではないのでしょうか?
プロセスの外からアクセスできなければ「グローバル変数」ではないのでしょうか?

「どこからでも」というのは本当にあいまいです。
言葉通りに解釈すれば、コンピュータの外だろうが、何万パーセク離れた天体だろうが、どんな場所でも対象になるはずです。
常識的に判断したいのはやまやまですが、妥当な線引きはできそうにありません。

「アクセスできる」もあいまいですね。
直接読み書きできなくても、アクセッサを介して読み書きできるのであれば、それは「アクセスできる」ということではないでしょうか?
実際、errnoマクロを介して読み書きするエラー番号の格納先なんかは完全にそんな感じですよね?

「グローバル変数」のようなあいまいな用語は便利ですが、コーディング規約などのルールを定める際には、それが一体何を意味するのか、明確に定義しなければ意味をなしません。

今月から「ブログは1000文字以上にすべし」というルールができてしまったので、少し長めに書きました。
さっき計測してみると、あっという間に2000文字を超えてしまいましたが。

    上に戻る