とか書きながら、養護するつもりはない。しかし、歴史を知っておく必要はあると思います。
Win32 API のリファレンスを見ていてよく見かける(無理矢理組み合わせた、かも)、「lpctstr
」という表記。これを、分解してみようかと思います。
まず、「p」から。これは、Pointer の p です。C 言語において、「文字配列」と「文字列へのポインタ」は、同じように扱えてしまえますが、実は違うものです。そのため、「ポインタであること」を明示するのは、読むとき、保守するときに有用です。
次、「l」。これ、よくわかりません。いろいろ読んでいるうちに「これかな?」と思ったのは、「local」か、「long」の「l」です。大昔、扱えるメモリ量が少なかったり、少ない故に小さいバイト数でいろいろ扱うために、DLL や EXE の境界を越えてポインタを渡せなかったようです。「ポインタ」に、「起点からの距離」を表すものと、「絶対距離」を表すものがあった様です。このうち、「起点からの距離」は、起点が違えば指す場所が変わってしまいます。あるいは、「GlobalHeap」という関数がありましたが、特定のプロセスのみで使えるアドレスと、Windows 全体で使えるアドレスか。そのため、これらを分けるために付けられたようです。はい、そこの人!!鵜呑みにしない。自分で確認すること。なんにしても、Windows 2000 の頃には、分ける必要がなくなっています。
次、「c」。これは、Const の c です。関数の引数に対して、「この引数の値は、関数内で変化させない」事を示すために付けられます。関数の入力、出力を明示するために使うわけです。これも、C++ になって const で修飾した場合、コンパイラがエラーを出します。このため、変数の修飾に使用して明示する必要はなくなっています。
次、「t」。これは、Multi-byte charactor set と、wide charactor set の、どちらにでも変化するよ、を表しています。そのため、文字(列)にしかつきません。Win32 API 関数の最後につく、A とか W と同じカテゴリです。
そして、「str」。これは String です。C では、char は「文字」だけでなく、「1バイトの数値」の意味も持っています。このため、「char a[10];
」だと、「10バイトのデータ」なのか、「最大9文字の文字列」なのか、わかりません。そこで、str を付け、「文字列」であることを明示したわけです。
他に、整数値につく「i」があります。これは、整数といえど、割り算をすると浮動小数点型に変換されることがあります。こういった、暗黙の変換を防ぐ(注意を向ける)意図を持ちます。
また、short の場合、演算結果がオーバーフローする可能性が高くなりますから、これをレビューで検出できるようにすることもあります。
あとは、符号のあるなしについても、ありますかね?signed char の 0x80 と、unsigned char の 0x81 を比べると、どちらが大きいか。これは、最近だとコンパイラが警告を出してくれます。また、符号の有無と同じように、縮小変換についても警告、あるいはエラーとなるようにコンパイラが修正されています。したがって、変数名に明示する必要はなくなっています。
このように、単に型を示していたのではなく、目視レビューで間違いを検出しやすくするための工夫だったわけです。で、コンパイラが検出するようになったからか、Visual Studio 2008 に付属する SDK のドキュメント(英語)では、これらのシステム ハンガリアンな記述がなくなっています(作業中かもしれない)。
このように、C/C++ では、意味がある事でした。しかし、すべての言語で意味があることではない、あるいは、同じ記号であっていいわけではありません。
VB や C# のコードで、型名を明示する必要はありません。特に、「クラスだから」と、「cls」を頭に付けているようなものは、全く意味がありません。
そんな無駄なことをするより、なぜそのような符号を付ける必要があるのかを知り、その上で、使用している言語にそれが必要なのか、同じようにしていいのか、他に追加することがあるか、といったことを考える事の方が重要ではないでしょうか。「システム ハンガリアン使うな」とは言いません。しかし、使う前に、それにどんな意味があるか、知って欲しいと思います。
投稿日時 : 2008年7月7日 21:54