一般にグローバル変数は、その非局在的な性質ゆえに、悪い作法だと考えられている。すなわち、グローバル変数は潜在的にどこかで変更される可能性があり、またプログラムの一部はそれに依存してしまう恐れがあるからである。グローバル変数はそれゆえ相互依存を生み出す無限の可能性を持っており、相互依存が高まることは複雑性を増大することにつながる。 () を参照。
しかしグローバル変数が適する状況もある。例えば、システム起動時に一度だけファイルから読み出し、以降は様々な関数を通して継続的によく使われるような設定情報を格納する変数を、関数に毎回引数として渡すことを避けるために使用できる。また、並列実行するスレッドやシグナルハンドラのように、呼び出し側/被呼び出し側の関係を持たないコード同士でセクション間情報を受け渡すためにも広く使われる。利用可能なメモリ容量が少ない組み込みシステムのような厳しい環境では、グローバル変数を使用せざるをえない場面もある。
各々のソースファイルが暗黙の名前空間（無名名前空間）を定義するような言語では、グローバルな名前空間を持つ言語に見られる問題の多くが解消されているが、一部の問題は適切なカプセル化を行わなければ解決できない。（ミューテックスのような）適切なロック無しにグローバル変数を使用しているコードは、保護メモリ内の読み出し専用値以外はスレッドセーフではない。
例.
void ChangeGlobal() {
 ChangeGlobal();
この出力結果は、以下のようになる。
グローバル変数を使用すると、ソフトウェアのソースコードを理解することが困難になる。グローバル変数の値はプログラムのどこからでも参照・変更できるため、グローバル変数がどのように使用されているか、またグローバル変数の値（すなわち状態）がどのように変化するかを理解するためには、プログラム全体を把握しなければならないからである。
以下にグローバル変数により難解になる例を示す。
上記をローカル変数を用いて書きなおした例を示す。