みずぴー日記

人間の再起動ボタンはハワイのビーチにある

論文紹介: The Evolution of C Programming Practices: A Study of the Unix Operating System 1973–2015

ICSE 2016勉強会に参加するために論文リストを確認していたら、40年間のC言語のプラクティスの変遷を追った論文がおもしろかったので紹介する。

対象の論文

要約

過去40年間のUnixソースコードを分析し、コーディングスタイルの変化を調査した。その結果、以下のことが分かった。

  • 新しい言語機能は価値のあるものならば採用される
  • レジスタ割り当てをコンパイラに任せるようになる
  • スペースをどこにいれるかなどのコードの書き方が統一されていく

分析対象

1972年以降にリリースされた計66個のUnixを対象とする。 これには以下のものが含まれる。

分析したリリースをタイムラインにまとめると以下のようになる。

f:id:mzp:20160607082146p:plain

(Figure 1: Timeline of indicative analyzed revisions and milestones. in Proc. of ICSE '16, p.754)

立てた仮説と結果

事前に立てた仮説と、分析によりその仮説が支持されたかどうかについて述べる。

なお以下に示すグラフは Figure 2: Long term evolution of programming practices. (Metrics appear in alphabetical order; the number following the metric name is adjusted R2). in Proc. of ICSE '16, p.755からの引用である。

H1: 技術の進歩によって、プログラミングプラクティスは変化する

画面解像度や通信速度などの向上にともない、識別子や行が長くなっていくと考えた。

分析の結果、以下の平均値が増加していることが分かった。

  • ファイル行数 (FILINE)
  • ファイル内のステートメント数 (FISTMT)
  • 行の長さ(文字数) (LICHAR)
  • 識別子の長さ (IDCHAR)

f:id:mzp:20160607210715p:plainf:id:mzp:20160607210726p:plainf:id:mzp:20160607210737p:plainf:id:mzp:20160607210742p:plain

一方、関数の平均行数(FULINE)はこの仮説と関連しているが、途中から減少している。これは複雑になりすぎたことへの反応であると考えられる。これに関してはH6で議論する。

f:id:mzp:20160607211059p:plain

これらにより仮説は支持された。

H2: コードの規模とともにモジュール性が増す

コード規模が増えるにつれて、開発者はモジュール化を進めるのではないかと考えた。

分析の結果、可視性を制御するためのstatic(DSTATIC)が増加していき上限値に達していたことが分かった。最近、若干減少しているのは、カーネルモジュールや共有ライブラリといった言語外の仕組みが導入されたためと考えられる。

f:id:mzp:20160607213856p:plain

これらにより仮説は支持された。

H3: 新しい言語機能は一定数に達するまで使用が増加していく

unsignedキーワードといった新しい言語機能は、使用箇所が増えていき飽和点に達すると考えた。

分析した結果、以下のキーワードの使用は増加していることが分かった。

  • const(DCONST)
  • enum(DENUM)
  • inline(DINL)
  • unsigned(DUNS)
  • void(DVOID)
  • volatile(DVOL)

f:id:mzp:20160607214804p:plainf:id:mzp:20160607214808p:plainf:id:mzp:20160607214811p:plainf:id:mzp:20160607214816p:plainf:id:mzp:20160607214820p:plainf:id:mzp:20160607214823p:plain

基本的に上昇傾向だが、 enumとinline は部分的に下降している。開発者が態度が変化した時期があると考えられる。

unsigned はここ数年で減少している。 これは以下の2つの要因が考えられる。

  • size_t が導入され、それが使われる箇所が増えた。
  • 64ビットアーキテクチャが導入され、扱える数値の幅を広げるために unsigned が使われることが減った

signed(DSIGN)はあまり使われていない。signedキーワードはchar型に符号付きの値を格納する際に利用できるが、現在では必要になることはない。

f:id:mzp:20160607215906p:plain

これらにより「その言語機能が便利ならば」という限定付きで仮説は支持された。

H4: 開発者はコンパイラレジスタ割り当てを信頼している

コンパイラ技術が発展しレジスタ割り当てが改善するにつれて、開発者はコンパイラレジスタ割り当てを信頼するようになっていったと考えた。

分析の結果、registerキーワードの使用(DREG)は1990年ごろから減少していることが分かった。

f:id:mzp:20160607220707p:plain

H5: コードの書き方は収束していく

Unixという一つのプロジェクトで作業してるため、共通のコーディングスタイルが採用され、コードベースは均一になっていくと考えた。

分析した結果、コードフォーマットのばらつき(FMINC)やインデントのばらつき(INDEV)は減少していったことが分かった。

f:id:mzp:20160607222806p:plain f:id:mzp:20160607223230p:plain

これにより仮説は強く支持された。

H6: ソフトウェアの複雑性には自己修正機構が働く

ソフトウェアが進歩に複雑性は増し、人間の限界を越えてしまう。 そのため、成功したプロジェクトでは複雑性を減少させる自己修正機構が働くと考えた。

分析した結果、以下の項目が、いったん複雑性を増したのち減少に転じるというパターンを示した。

f:id:mzp:20160607224130p:plainf:id:mzp:20160607224142p:plainf:id:mzp:20160607224210p:plainf:id:mzp:20160607224214p:plain

goto(DGOTO)についても同様のことが言える。 gotoは長期間減少しつづけていたが最近は増加している。 gotoの有用性に気付いたのかもしれない。

f:id:mzp:20160607225638p:plain

H7: コードの可読性は増す

開発者コミュニティで管理しやすくするために、可読性は増していくと考えた。

これを調べるために、以下の項目を分析した。

  • インデントのためのスペースの平均値(INSPC)
  • ステートメントの密度(DSTMT)
  • コメントの文字数の密度(DCMCHAR)
  • コメントの文字数の平均値(CMCHAR)
  • コメントの密度(DCM)
  • TODOコメントの密度(DKLUDGE)

f:id:mzp:20160607231046p:plainf:id:mzp:20160607231056p:plainf:id:mzp:20160607231108p:plainf:id:mzp:20160607231113p:plainf:id:mzp:20160607231117p:plainf:id:mzp:20160607231123p:plain

コメントの密度とコメントの文字数の密度が増加したのち減少しているのは、より長い識別子が使えるようになって、自己文書化が進んだためと考えられる。

ステートメントの密度は減少傾向にあるが、2000年ごろから増加している。これはコメントのついていないステートメントが増えていることを示す。インデントのためのスペースの平均値も減少していたものの、最近は増加している。 そのため、Unixソースコードの可読性が今も増加していることの確証は得られなかった。

まとめ

長年にわたるUnixの発展を追跡することで、Unixの開発者が以下のことを行なってきたことが分かった。

  • ハードウェアの進歩にあわせてコーディングスタイルを変化させる
  • 複雑度が増すにしたがいモジュール化を促進させる
  • 価値のある新しい言語機能を採用する
  • コンパイラレジスタ割り当てをまかせる
  • コードの書き方に関して合意に達する

また、ソフトウェアの複雑性と自己修復機構が関連していることと、文書によるコード構成の改善が頭打ちになっていることも発見した。