プログラミングにおける様々なstaticまとめ

コード書いてる時にちらほら見かけるstatic
こいつらっていったいなんだっけ?

staticメモリ

プログラムが扱うメモリは大きく分けてstatic/stack/heapの3領域あります。

  • static: あらかじめ予約されたサイズ固定の領域
  • stack: 動的に確保できる領域。スコープが決まっており、そこを抜けると強制的に解放される。高速
  • heap: 動的に確保できる領域。任意のサイズ、任意の順で確保開放できる。低速。

ここでいうstaticと言うのは「プログラム全体を通してstaticに確保されるメモリ」という意味です。
プログラムした時点でサイズが決定し、プログラム起動時にまとめて確保されてしまいます。

C言語では以下の2つが該当します。

  • global変数
  • 関数内でstatic宣言された変数

大概はheapで確保したメモリへのポインタをglobal変数に格納するという合わせ技で使われます。
ちなみにstack変数のポインタを格納しても勝手に開放されるので意味ないです。と言うかバグです。

コンパイル単位制限

C/C++でしかお目にかからない構文です。

  • global変数の頭につける(global static変数)
  • 関数宣言の頭につける(static関数)

数あるstaticの中で一番意味不明な振る舞いをします。

最近はスクリプト言語が多いので忘れがちですが、プログラムは以下のステップで作成されます。(末尾はC言語の場合の拡張子)

  1. ソースコードにテキスト処理を施す(プリプロセッサ
  2. ソースコードからオブジェクトファイルを作る(コンパイル
  3. オブジェクトファイル同士を静的に結合してライブラリにする(静的リンク)

global変数や関数はスコープが無いため、同名があればコンパイル時、静的リンク時にエラーになってしまいます。
しかしstatic宣言をすることで、その名前はコンパイル時にしか使用しませんよ、という制約を加えることができます。
(つまり静的リンク時に衝突しない)

インスタンスに対してstatic

多分一番お目にかかるstaticです。
クラスのメンバに付与することで効果を発揮します。

staticフィールド

本来クラスはインスタンスの雛形で、フィールドはインスタンスごとに固有のメモリ領域を持ちます。
しかしこのstatic指定を追加すると、フィールドはインスタンスではなくクラスで管理され、全インスタンスで共有されます。
オブジェクト指向とは何だったのか。

staticメソッド

staticフィールドのみにアクセスし、通常のフィールドにアクセスできないメソッドです。
引数だけで結果が確定する関数などでも使用されます。

staticクラス

staticなメンバしか保たないクラスの宣言に使います。
基本普通のクラスなんですが「どうせ全部staticなのだからnew禁止しといてあげるね♪」というおせっかいがつきます。

まとめ

ややこしくて仕方がない。
違う概念に同じ名前をつけるの辞めてほしいですね。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です