ろぐれこーど

限界組み込みエンジニアの学習記録とちょっぴりポエム

ハンガリアン記法について再考してみる

ハンガリアン記法という一種のコーディングルールがありますが、この是非について自分なりに考えてみました。異論あれば後学のために教えていただけると助かります。

現在の開発基準では多くの場合でハンガリアン記法は推奨されていませんが、残念ながら未だに使われている現場もあり、特に組み込み系では現役バリバリで運用されていたりします。ここではハンガリアン記法のメリット・デメリットと、自分が所属する車載系ソフト開発における現実問題について説明します。

ハンガリアン記法とは

ハンガリアン記法(ハンガリアンきほう、英: Hungarian notation)あるいはハンガリー記法(ハンガリーきほう)とは、プログラマがプログラムのソースコードを書く際に変数名やクラス名などの識別子に特別な接頭文字ないし接尾文字をつけることで、他の人がその識別子を見たときに識別子の使用方法・データ型情報・スコープなどが分かるようにするための命名法である。

引用元:https://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%B3%E3%82%AC%E3%83%AA%E3%82%A2%E3%83%B3%E8%A8%98%E6%B3%95

本来は型に現れない情報(絶対/相対座標、ドル/円など)を接頭語や接尾後として付与することで、コード上の意味的な間違いをなくすためにこの記法が使われていました。これをアプリケーションハンガリアンと呼び、対して型やスコープの識別子を付与する記法をシステムハンガリアンと呼びます。多くの場合、ハンガリアン記法と言うと後者を指し、現場でも後者が使われていることが多いでしょう。以降もシステムハンガリアンについて述べます。

メリット

オブジェクト指向がサポートされていない言語で)スコープを明確にできる

C言語のような、言語仕様としてオブジェクト指向がサポートされていない言語による設計では、変数や関数のスコープが曖昧になりがちです。もちろんC言語でもオブジェクト指向設計は可能ですが、言語仕様で決めきれられていない分、設計ルールをチームや組織で定めておく必要があります。ですが、ただでさえ記述量が多くなりがちなC言語で厳密なルールを制定してかつ運用し続けるのは、限られたリソースでは困難です。全てのルールを運用するのは無理でも、ハンガリアン記法で変数スコープだけでも明確にしてやれば、現実的に耐えうる負担でコードレベルで担保できる品質を上げることができると思います。

型を意識して演算できる

多くの言語で暗黙の型変換がサポートされていますが、実際の設計で型変換を暗黙に行うのは良い実装とは言えません。演算時に必要な型変換は明示的にキャストするのが自然でしょう。そうした場合、計算式に異なるデータサイズの変数が含まれている場合はひと目で実装が誤っていることが確認できます。

ただ現在では多くの高機能エディタやIDEで、変数の型が簡単に確認できます。コーディングする環境によってはこのメリットはほぼないでしょう。それでも複雑な計算式の実装には少しは見やすくなる可能性もあります。後述しますが、このメリットは個々人の開発環境に対する意識に依存するでしょう。

(型の緩い言語では)変数情報が把握しやすくなる

Pythonのような変数宣言・定義を必要としない、いわゆる”型が緩い”言語では、変数の保持する情報を表現する手段としてハンガリアン記法は意味を持つと思います。同じ変数を複数の意味で使用するのは可読性を下げるため、普通はコロコロ型を変えることはしないと思いますが…おそらくこういった言語で型がわからなくなる場合、設計上の他の問題が起こっている可能性があります(関数が長すぎる等?)

デメリット

変更時の負担が大きくなる

一番よく挙げられるデメリットがこれです。型の変更時、他の部分と整合性が取りにくくなることが想像できます。実際にスコープの広い変数をそう何度も書き換えることがあるかは疑問です。私は車載の組み込み開発しか経験がないので、他の開発現場の内情がどうなのかは気になるところです。

変数名が長くなりすぎる

接頭語・接尾語の分だけ当然、変数名が長くなります。一行に含まれる文字数上限がコーディング規約として定められている場合、何度も改行することになるので可読性が落ちます。また階層が深いメンバにアクセスするときや、メソッドチェーン的に記述するときはその分だけ接頭語・接尾語が積み上がることになるので、非常に読みにくくなります。そのせいで、本来つけるべき変数名が不自然に省略されたりすると最悪です。個人的にはこれが一番デメリットな気がしています。

現実問題

上で述べたメリットは開発環境や設計ルール次第で薄らいでしまうため、やはりデメリットが目立ちます。ですが現場ではハンガリアン記法を廃止しきれない理由があります。(あくまで私自身の経験です)

変更に対する品質担保が現実的に不可能

ソフトウェアの品質は主にテスト(単体、結合、ソフトウェアテスト)と開発プロセスで担保されます(より一般的にいえばプロセスとドキュメントになるかも)。高信頼性が要求されるソフトでは、このテストを実機環境に近い状態で行うことが好まれます。例えば組み込みであれば、Cソースの静的解析による単体テストよりも、ビルド後生成される実機コードを使用した単体テストのほうが、コンパイラの影響も加味したテストができるためです。そうなると全体としてテストの工数が増えることになります。(CIツール使えばいいじゃん、と思う方もいるかと思います。ただ製品によっては、内部的なインフラ整備よりも客先への説明責任や国際規約を満足するための"ドキュメント"の作成を優先させられることも往々にしてあります)

加えて、すべての変更に対するテストを実施し、そのトレースが取れることが求められます(これはどの業界でも大差ないと思いますが)。ハンガリアン記法をやめようと思っても、その変数が使われている機能やコンポーネントすべてのテストを再実施するのは現実的に不可能です。たとえ自動テスト環境が完璧に揃っていても、万が一にも変更によって不具合を埋め込むことにより死人が出る可能性があるなら、それを避けようとする判断もわからなくはありません。

開発環境を刷新しない/できない

これは完全に人によりますが、組み込み業界で高機能なエディタやIDEを頑なに使おうともしない人がいることも事実です(デフォルトのままのサクラエディタだったり、メモ帳を使う猛者もいます)。そしてそういった新しいものや効率化に積極的な人の割合は、他IT系の業界より低い印象です。

また車載系に限った話で言えば、開発環境を刷新できない以下のような事情があります。

  • 完全新規開発はほぼない
  • 派生開発がやたら多い
  • 量産〜生産終了までが非常に長く、客先要求には応じる必要がある(環境を保存しなければならない)

新規開発はほぼないため、実績のあるソフト(=レガシーコードを含むソース)をベースに開発が進められます。派生開発についても同様です。3つ目は車載特有ですが、他の組み込み製品と比較して、一つの製品が生産終了するまでの期間が非常に長いです(10年以上)。この期間中は客先の要求や問い合わせ、不具合の対応をする必要があるため、開発環境を安易に変えられません。加えて生産ピークを過ぎると売上への貢献度も下がるため、そのような製品の開発環境改善に工数をかけられないことも一つの要因です。

まとめ

現場で使われているハンガリアン記法(システムハンガリアン)のメリット・デメリットと、現実的に撤廃できない理由を考えてみました。レガシーとうまく付き合っていきながら、開発の生産性を上げていきたいものです。

参考

https://webrage.jp/techblog/external_quality_inner_quality/

https://qiita.com/inabe49/items/a4eedae3b7c44fe04c0d