原文:http://www.byteshift.de/msg/hungarian-notation-doug-klunder
原文との対訳として読みたい方へ:このページをローカルに保存して、スタイルシートの original クラスの display 属性を none から block に変更してみてください。

訳注※:上記リンク先のHTML文書には、さらに大元の非HTML文書が存在しているようです。そこからHTMLへの変換時に体裁の崩れている部分があるようで、推測で加筆/修正しています。そんな中でも大きく修正した部分(主にコードサンプル)には、「訳注※」としてコメントと原文とを記述しています。


Troff version at unlser1.unl.csi.cuny.edu Troff バージョンはこちら unlser1.unl.csi.cuny.edu

Bill Campbell and Joel Spolsky (joelonsoftware.com) state to have be informed personally by Doug Klunder that this text is in the "public domain" - see copyright info. I claim no rights to my HTML version (byteshift webdesign/info@byteshift.de), yet a backlink would be appreciated, should you want to mirror this page. 本稿が "パブリックドメイン(public domain)" であることを、Bill Cmpbell と Joel Spolsky (joelonsoftware.com) は Doug Klunder から直接知らされたことを明記しておく - 著作権 情報 を参照してほしい。私はこの HTML バージョンの権利を主張しない。しかしながらこのページをミラーしたいと望むなら、リンクをお願いしたい。

HUNGARIAN NAMING CONVENTIONS ハンガリアン命名記法

Doug Klunder

January 18, 1988

September 10, 1991

1. INTRODUCTION 1. 導入

This document describes a set of naming conventions used by the IEMIS project in development of the software. The initial naming conventions where taken from a NAMING CONVENTIONS document authored by Doug Klunder at MicroSoft. These conventions commonly go by the name "Hungarian," referring both to the nationality of their original developer, Charles Simonyi, and also to the fact that to an uninitiated programmer they are somewhat confusing. Once you have gained familiarity with Hungarian, however, we believe that you will find that the clarity of code is enhanced. For convenience, this memo first describes how to use Hungarian, and then describes why it is useful; the general approach is from a programming viewpoint, rather than a mathematical one. この文書は、IEMIS のソフトウェア開発において使用されている命名規則に付いて説明する。NAMING CONVENTIONS 文書に由来する最初の命名規則は、マイクロソフトの Doug Klunder により書かれた。これらの規則は一般に "ハンガリアン記法(Hungarian)" という名で知られている。その名前は元もとの作成者である Charles Simonyi の国籍を表し、また同時に初心者プログラマをやや混乱させる元となっている。しかしながらひとたびハンガリアン記法に慣れ親しめば、コードの明確性が高まることに気付くだろう。簡便性のために、この文書はまずハンガリアン記法の使用法から説明し、次にそれが有益である理由を説明する。全体的なアプローチはプログラミングの視点から見たものであり、数学的な視点からのものではない。

2.THE RULES 2. 規則

Hungarian is largely language independent; it is equally applicable to a microprocessor assembly language and to a fourth-generation database application language (and has been used in both). However, there is a little flavor of C, in that arrays and pointers to arrays are not clearly distinguished. While this may sound confusing, in practice there is little ambiguity. ハンガリアン記法は大部分が言語から独立している。マイクロプロセッサのアセンブリ言語にも、第 4 世代のデータベースアプリケーション言語にも、等しく適用できる(そして実際にその両方で使用されている)。しかしながら多少 C 言語向けの要素が存在し、配列と配列へのポインタとが明確に区別されない。これは混乱しそうに思えるかもしれないが、実際にはあいまいさはほとんどない。

< prefix > < base type > < qualifier >

2.1. VARIABLES 2.1. 変数

The most common type of identifier is a variable name. All variable names are composed of three elements: prefixes, base type, and qualifier. (These are also referred to as constructors, tag, and qualifier). Not all elements are present in all variable names; the only part that is always present is the base type. This type should not be confused with the types supported directly by the programming language; most types are application specific. For example, an 1b1 type could refer to a structure containing symbol information; a co could be a value specifying a color. もっとも一般的な種類の識別子は、変数名である。あらゆる変数名は 3 つ要素、接頭辞・基本型・限定子から構成される(これらは、コンストラクタ・タグ・限定子とも言及される)。常に与えられるのは基本型だけであり、すべての変数名にすべての要素が与えられるわけではない。ここで言う「型」をプログラミング言語が直接サポートする型と混同するべきではない。大部分の型はアプリケーションに固有である。例えば、型 lbl はシンボル情報を含む構造体を参照するかもしれないし、co は色(color)を表す値かもしれない。

2.1.1. Base Types (Tags) 2.1.1. 基本型(タグ)

Type that are not defined must be added As the above examples indicate, tags should be short (typically two or three letters) and somewhat mnemonic. Because of the brevity, the mnemonic value will be useful only as a reminder to someone who knows the application, and has been told what the basic types are; the name will not be sufficient to inform (by itself) a casual viewer what is being referred to. For example, a co could just as easily refer to a geometric coordinate, or to a commanding officer. Within the context of a given application, however, a co would always have a specific meaning; all co's would refer to the same type of object, and all references to such an object would use the term co. 未定義の型は前述の例のような形で追加されなければならず、タグは短く(一般には 2 文字か 3 文字)、多少覚えやすいものであるべきである。この短さのため、ニーモニックはアプリケーションを知る人にとってのリマインダとしてのみ使用され、それらの基本型が何であるかを表す。その名前は(それ自体では)、臨時の閲覧者にそれが何を表しているかを知らせるには不十分だろう。例えば co は幾何学座標(geometric coordinate)を表しているのかもしれないし、艦長(commanding officier)を表しているのかもしれない。しかしながらある特定のアプリケーションの枠内においては、co は一貫して固有の意味を持ち、すべての co が同じオブジェクトの型を参照し、その種のオブジェクトへのすべての参照は co を使用するだろう。

One should resist the natural first impulse to use a short descriptive generic English term as a type name. This is almost always a mistake. One should not preempt the most useful English phrases for the provincial purposes of any given version of a given program. Chances are that the same generic term could be equally applicable to many more types in the same program. How will we know which is the one with the pretty "logical" name, and which have the more arbitrary variants typically obtained by omitting various vowels or by other disfigurement? Also, in communicating with other programmers, how do we distinguish the generic use of the common term from the reserved technical usage? In practice, it seems best to use some abbreviated or form of the generic term, or perhaps an acronym. In speech, the tag may be spelled out, or a pronounceable nickname may be used. In time, the exact derivation of the tag may be forgotten, but its meaning will still be clear. 短く説明的で一般的な英語の用語を型名として使用するという自然な衝動は、抑えるべきである。大抵の場合それは間違いである。ある特定のプログラムの任意の特定のバージョンの狭い目的のために、一般的すぎる英語のフレーズを先取りするべきではない。そのような一般的用語は、同じプログラム内のさらに多くの別の型にも適用可能かもしれない。私たちは、どちらがより "論理的な(logical)" 名前であるかや、どちらがより独断的な(一般に様々な母音を省略するなどの変形によって得られる)変化形であるかを、どのようにして判断すればよいだろうか? また、別のプログラマとやりとりするとき、予約済みの技術用語と一般的な用語とを、どのようにして区別すればよいのだろうか? 実際問題として、一般的用語、またはその省略形か接頭語かを使用するのが最善と思える。会話の中ではタグを省略しないか、ニックネームを使用してよい。時がたつにつれてタグの正確な由来は忘れられるかもしれないが、その意味は明確さを保ち続けるだろう。

As is probably obvious from the above, it is essential that all tags used in a given application be clearly documented. This is extremely useful in helping a new programmer learn the code; it not only enables him (or her) to decode the otherwise cryptic names, but it also serves to describe the underlying concepts of the program, since the data types tend to determine how the program works. It is also worth pointing out that this is not nearly as onerous as it sounds; while there may be tens of thousands of variables in a program, the number of types is likely to be quite small. 上記の内容から明らかかもしれないが、特定のアプリケーション内で使用されるすべてのタグを明確に文書化することが必要不可欠である。これは新しいプログラマがコードを理解する際に非常に役に立つ。彼(または彼女)が暗号的な名前を解読できるようになるだけでなく、そのプログラムの基礎をなす概念の説明を提供する(データ型はプログラムがどのように動作するかを決定する傾向があるためである)。これは思ったほど煩わしいことではないことも指摘しておく。プログラム内には何万もの変数が存在するかもしれないが、それに比べれば型の数は極めて少ない。

Although most types are particular to a given application, there are a few standard ones that appear in many different ones; synonyms for these types should never be used: 大部分の型は特定のアプリケーションに特有なものになるが、多くの異なるアプリケーションに現れる標準的な型も少数だが存在する。そのような型の類義語は決して使用するべきではない:

f
a flag (boolean, logical). The qualifier (see below) should describe the condition that will cause this flag to be set (e.g., fError would be clear if there were no error, set if one exists). This tag may refer to a single bit, a byte, or a word; often it will be an object of type BOOL (defined by the application, usually as int). Usually the object referred to will contain either 1 (fTrue, TRUE) or 0 (fFalse, FALSE). In some instances, other values may be used, either for efficiency or historical reasons; such a use usually indicates that another type may be more appropriate. フラグ(ブール、論理)。限定子(下記参照)は、このフラグがセットされる条件を説明するべきである(例えば fError はエラーがない場合にクリアされ、エラーがある場合にセットされる)。このタグは単一のビット、バイト、ワードを参照する可能性があり、しばしば BOOL 型(アプリケーションにより定義され、通常は int である)のオブジェクトである。通常このオブジェクトは 1 (fTrue, TRUE) または 0 (fFalse, FALSE)のどちらかを表す。場合によっては、効率上または歴史的な理由により別の値が使用されてもよいが、通常そのような使用法は、より適した別の型があることを示している。
ch
a one-byte character. Note that this is not adequate for Kanji. 1 バイト文字。漢字には適さないことに注意してほしい。
st
a Pascal-type string (first byte is count, remainder is the actual characters). Typically refers to a pointer to the actual memory. This should be the most common type of string used in the Applications group; it is more efficient than an sz (below). パスカル形式の文字列(先頭のバイトはカウントで、それ以降が実際の文字列)。一般には実メモリのポインタを参照する。これはアプリケーショングループにおける文字列のもっとも一般的な型のはずであり、sz(後述)より効率的である。
sz
a zero-terminated string, or a pointer to it. These are most often used to interface to an operating system (or equivalent) that requires them; for most other uses, an st is preferable. Unfortunately, C string constants are normally zero-terminated, so it takes a little more effort to use st's; the effort is worth it. The Applications Development compiler proves ways to make strings constants st's. ゼロで終了する文字列、またはそれを指すポインタ。これはほとんどの場合、これらを必要とするオペレーティングシステム(またはそれに相当するもの)へのインターフェイスとして使用され、それ以外の場合にはたいてい st が好ましい。あいにく C 言語の文字列定数は通常ゼロ終端であり、st を使用するには多少の努力を要するが、努力する価値はある。アプリケーション開発コンパイラは、文字列を定数の st にする方法を検証する。
fn
a function. Since about the only thing you can do with a function is take its address, this almost always has a "p" prefix (see below). For this reason, in some applications fn is itself used to mean pointer to a function. 関数。関数に対してはそのアドレスを取得することしかできないため、これはほとんどの場合、接頭辞 "p" (後述)を持つ。そのため一部のアプリケーションでは、fn だけで関数へのポインタを意味するものとして使用される。
fl
a file structure supplied by operating systems. オペレーティングシステムの提供するファイル構造体。

There are some more types that appear in many applications; they should only be used for the most generic purposes: 多くのアプリケーションに現れる型がさらにいくつか存在する。これらはもっとも一般的な目的にためにのみ使用されるべきである:

w
a word (typically 16 bits). For most purposes, this is an incorrect usage, since the usage of the word is specific to a particular type of work, and should be so distinguished. Correct usages are generally limited to generic subroutines (e.g., sort an array of words) that can deal with a number of different types; another common use is in conjunction with the prefix c (see below), to produce a count of words (the size) for some object. ■The exact meaning of w is also somewhat loose;it sometimes means a signed quantity and sometimes unsigned. word (一般に 16 ビット)。通常、word 型は特定の種類の作業に使用され、したがってそれぞれを区別するべきであるため、ほとんどの場合これは誤用である。正しい用法は汎用サブルーチン(例えばワードの配列をソートするサブルーチン)に限られる。また別の一般的な使用法は、何らかのオブジェクトのワード数(サイズ)を提供するために、接頭辞 c (後述)とともに使用される場合である。w の正確な意味もややあいまいであり、符合ありの数量を表したり、符合なしを表したりする。
b
a byte (typically 8 bits). The same warnings apply to this as to w. バイト(一般に 8 ビット)。w の場合と同じ注意事項が適用される。
l
a long (typically 32 bits). The same warnings apply to this as to w. long (一般に 32 ビット)。w の場合と同じ注意事項が適用される。
uw
Unsigned word. 符号なし word。
ul
Unsigned long. 符号なし long。
d
Double (double precision) double (倍精度)
r
Float (single precision) float (単精度)
bit
a single bit. Typically used to specify bits used within other types. This concept is usually better handled with the "f" and "sh" prefixes (see below). 単一ビット。一般に、別の型の中で使用されるビットを特定するために使用される。通常この概念には、接頭辞 "f" および "sh" (後述)の方が適している。
v
a void. This corresponds to the C definition of void, meaning that the type is not specified. This type will never be used without a "p" prefix since it is not possible to have an unspecified type for a variable; conceivably there are additional prefixes (e.g., ppv), but such a usage is unlikely. It is perfectly valid to assign a pv to a pointer of any other type, or vice versa. The major use of this type is for generic subroutines (such as allocate and free) which return or take as arguments pointers of various types. void。これは C 言語の void の定義に対応し、型が特定されないことを意味する。変数に不定な型を持たせることはできないため、接頭辞 "p" を伴なわせずにこの型を使用してはならない。あるいは追加の接頭辞があるかもしれないが(例えば ppv)、そのような使用法は想像しにくい。pv を別の型のポインタに割り当てたりその逆を行うことは、完全に正当である。この型の主な使用法は、様々な型のポインタの引数を受け取ったり返したりする汎用サブルーチン(例えばメモリの割り当てと解放)のためである。

There a few types that are used widely within the applications group, but may not be applicable to others: アプリケーショングループ内で広く使用される小数の型が存在するが、他には適用できないだろう:

env
an environment. Used to implement non-local goto's (SetJmp and DoJmp). The exact format of an env (including size), varies from system to system. 環境(environment)。非ローカルの goto を実装するために使用される(SetJmp および DoJmp)。env の正確なフォーマット(サイズを含む)は、システムによって異なる。
sb
a segment base. The part of a segmented pointer that determines the segment. The exact implementation varies from system to system. These are used directly in some applications for efficiency; the same results can be obtained (less efficiently) through the use of far or huge pointers. セグメントベース(segment base)。セグメント化されたポインタのセグメント部を決定する。正確な実装はシステムによって異なる。一部のアプリケーションにおいてこれらは直接効率的に使用され、far ポインタまたは huge ポインタを通しても同じ結果を得られる(効率は劣る)。
ib
an offset. The part of a pointer that determines the offset within a segment. These are used directly in some applications for efficiency; the same results can be obtained (less efficiently) through the use of far or huge pointers. For the literal-minded, ib is not really a new type at all; it is simply the prefix i (index) applied to the type b (byte), with the viewpoint that a segment is just an array of bytes. Many people prefer to consider it a true indivisible base type. オフセット。ポインタのセグメント内のオフセット部分を決定する。これらは一部のアプリケーションにおいて効率的に直接使用され、far ポインタまたは huge ポインタを通しても同じ結果を得られる(効率は劣る)。実際には ib は新しい型ではなく、セグメントが単なるバイト配列であるという観点から、型 b (バイト)に接頭辞 i (インデックス)を単純に適用したものである。多くの人はこれを、分割できない基本型と見なすことを好む。

2.1.2. Prefixes (Constructors) 2.1.2. 接頭辞(コンストラクタ)

Base types are not by themselves sufficient to fully describe the type of a variable, since variables often refer to more complex items. The more complex items are always derived from some combination of simple items, with a few operations. For example, there may be a pointer to an lbl, or an array of them, or a count of co's. These operations are represented in Hungarian by prefixes; the combination of the prefixes and base type represent the complete type of an entity. Note that a type may consist of multiple prefixes in addition to the base type (e.g., a pointer to a count of co's); the prefixes are read right to left, with each prefix applying to the remainder of the type (see examples below). The term constructor is used because a new type is constructed from the combination of the operation and the base type. 基本型だけでは変数の種類を完全に説明するのに不十分である。変数はしばしば、より複雑な項目を表すためである。通常そのようなより複雑な項目は、少数の働きを持つ単純な項目の組み合わせから導き出される。例えば lbl へのポインタ、それらの配列、co のカウントなどがあり得る。ハンガリアン記法においてこれらの操作は接頭辞により表され、その接頭辞と基本型とにより実体の完全な型を表す。型は基本型に加えて複数の接頭辞から構成されてもよいことに注意してほしい(例えば co のカウントへのポインタ)。接頭辞は右から左に読み、それぞれの接頭辞は型の残りの部分に適用される(後述の例を参照)。操作と基本型との組み合わせから新しい型が構築されるため、コンストラクタという用語が使用される。

In theory, new prefixes can be created, just as new types are routinely created for each application. In practice, very few new prefixes have been created over the years, as the set that already exists is rather comprehensive for operations likely to be applied to types. Prefixes that have been added tend to deal with the specifics of machine architecture, and are variations on existing prefixes (i.e., different flavors of pointers). Once can go overboard in refusing to create a new prefix, however; some new concepts really are logically expressed as prefixes, not types. A couple of examples of incorrect usage in the list below derived from the reluctance to create a new prefix. 理論上は新しい接頭辞を生成できる。それぞれのアプリケーションのために日常的に新しい型が生成されるのと同じである。既存の集合は型に適用されそうな操作をかなり広範囲に網羅しているため、実際のところここ数年で新しく登録された接頭辞はごく少数である。追加された接頭辞は、マシンアーキテクチャに固有のものを扱い、既存の接頭辞のバリエーション(つまりポインタの異なる特徴)である傾向がある。新しい接頭辞を作るのを拒否するために一度外に出ることができるが、一部の新しい概念は型ではなく接頭辞として論理的に表現される。後述のリスト内の誤った使用法の例のいくつかは、新しい接頭辞を作成することへの不本意に由来したものである。

The standard prefixes are: 標準的な接頭辞は以下の通り:

p
a pointer. A 32 bit address. (assumed to be a far pointer). ポインタ。32 ビットアドレス。(far ポインタを前提としている)
rg
an array, or a pointer to it. The name comes from a mathematical viewpoint of an array as the range of a function (see mp and dn below). For example, an rgch is an array of characters; a pch could point to one of the characters in the array. Note that it is perfectly reasonable to assign an rgch to a pch; pch points to the first character in the array. 配列、または配列へのポインタ。名前は関数の範囲としての配列の数学的な観点に由来する(後述の mp および dn を参照)。例えば rgch は文字(character)の配列であり、pch はその配列内のひとつの文字を指し示すことができる。rgch を pch に割り当てるのは完全に正しく、pch は配列内の最初の文字を指すことに注意してほしい。
i
an index into an array. For example, an ich is used to index an rgch. 配列内のインデックス。例えば ich は rgch のインデックスに使用される。
c
a count. For example, the first byte of an st is a count of characters, or a cch. カウント。例えば st の先頭のバイトは文字数のカウント、つまり cch である。
d
a difference between two instances of a type. This is often confused with a count, but is in reality quite separate. For example, a cch could refer the number of characters in a string, whereas a dch could refer to the difference between the values 'a' and 'A'. The confusion arises when dealing with indices; a dich (difference between indices into a character array) is equivalent to a cch (count of characters); which one to use depends on the viewpoint. This gets most confusing when dealing with base types that are in effect indices, though not specifically labelled as such. For example, a spreadsheet could have a rw type that indicates a row in the spreadsheet; it does not contain the actual data for the row, but is simply a one-word integer specifying the row number. A type specifying a count of rows (not rw's) would correctly be a drw (difference between row numbers), not a crw (count of row numbers). ある型の二つのインスタンスの差分。しばしばこれはカウントと混同されるが、実際にはまったく別物である。例えば cch が文字列内の文字数を表すのに対して、dch は 'a' と 'A' との差異を表す。混乱が生じるのはインデックスを扱う場合である。dich(文字配列のインデックスの差分)は cch(文字数)に等しく、どちらを使うかは観点による。明確にそのようにラベル付けられていないが実際にはインデックスである基本型を扱う場合に、これはもっとも混乱する。例えばスプレッドシートは、スプレッドシート内の行のインデックスである rw 型を持つかもしれないが、それはその行の実際のデータを含むわけではなく、単に行番号を表す 1 ワードである。(rw の数ではなく)行の数を表す型は、crw (行数のカウント)ではなく、drw (行番号の差分)となるだろう。
h
a handle. This is often a pointer to a pointer (used to allow moveable heap objects). The types of the pointers may vary amoung applications; the two most common cases are a near pointer to a near pointer (h is equivalent to pp) and a far pointer to a far pointer (h is equivalent to lplp). Most commonly used for interface to an operating system; within applications, moveable objects can be handled through huge pointers. In some systems (e.g., Windows) a handle is not a pointer to a pointer. To avoid confusion it may be best to use pp (or lplp) as prefixes when the application is actually going to do the indirection, and reserve h for instances in which the handle is just passed on to the system. Doing this prevents the most common misuse of h in defining a handle to an array (or other implicit pointer type); uses of hsz to imply two indirections to obtain a character are incorrect. This should properly be done as a psz or, if h must be used, as an hasz (see 'a' prefix below). ハンドル。これはしばしば、ポインタへのポインタである(移動可能なヒープオブジェクトのために使用される)。このポインタの種類はアプリケーションによって様々だが、一般的な二つのケースは、near ポインタへの near ポインタ(h は pp と等価)と、far ポインタへの far ポインタ(h は lplp と等価)とである。もっとも一般的な使われ方はオペレーティングシステムへのインターフェイスとしてである。アプリケーション内では移動可能なオブジェクトは huge ポインタで扱える。一部のシステム(例えば Windows)では、ハンドルがポインタへのポインタではない。混乱を避けるために最適な方法は、アプリケーションが本当に間接指定をする場合に接頭辞として pp (または lplp)を使用し、単にハンドルがシステムに渡される場合などのために h を予約しておくことだろう。そうすることで、配列(または他の暗黙的なポインタ型)へのハンドルを定義する場合のよくある間違いを避けられる。文字を取得するために二つの間接指定を意味する hsz を使用するのは誤りである。そのような場合は psz を使用するか、h を使用しなければならないのであれば hasz (後述の接頭辞 'a' を参照)を使用することで適切に扱えるはずである。
gr
a group, or a pointer to it. This is similar to an rg, but is used for variable size objects. In this case an index (i) is not particularly useful, since it can not be used directly to obtain an object (one can, of course, write a routine that will take the gr and i, walk through the data in a type-specific manner, and derive a pointer to the object desired). This is a rarely used prefix, and in some code, grp has been used instead of gr. グループ(group)、またはグループへのポインタ。これは rg に似ているが、可変サイズのオブジェクトに使用される。この場合のインデックス (i) はオブジェクトを直接取得するために使用することができないため、特に便利ではない(もちろん、gr と i とを受け取って型固有の方法でデータを走査し、求めるオブジェクトのポインタを抽出するルーチンを書くことはできる)。これはまれにしか使用されない接頭辞であり、一部のコードにおいては、gr の代わりに grp が使用される。
b
an offset. This is typically used in conjunction with a gr, in place of an i, in order to get around the problem mentioned above. This offset is in terms of bytes, so pfoo-(BYTE *)grfoo+bfoo. As with gr, this is a somewhat rare usage in current code. b originally stood for base-relative pointer, but should really be considered to be an offset within a data structure; true base-relative pointers are just near pointers (p); the base is the segment they are within. オフセット。一般に前述の問題を回避するために、gr と共に i の代わりに使用される。このオフセットはバイトの観点であり、したがって pfoo=(BYTE *)grfoo+bfoo である。gr と同じく、これも現在のコードではまれにしか使用されない。そもそも b はベース相対ポインタを表すが、実際にはデータ構造体内のオフセットと見なされるべきものである。本当のベース相対ポインタは near ポインタ(p)であり、ベースはその範囲のセグメントである。

訳注※:上記の「pfoo=(BYTE *)grfoo+bfoo」は、原文では「pfoo-(BYTE *)grfoo+bfoo」となっています。
mp
an array. This prefix is followed by two types, rather than the standard one, and represents the most general case of an array. From a mathematical viewpoint, an array is simply a function mapping the index to the value stored in the array (hence mp as an abbreviation of map). In the construct mpxy, x is the type of the index and y is the type of the value stored in the array (hence mp as an abbreviation of map). In the construct myxy, x is the type of the index and y is the type of the value stored in the array. In most cases, the only type that is important is the type of the value; the index is always an integer with no other meaning. In this case, an rg is used; this means that the rgs is equivalent to an mpixx. (This also explains the weird prefix rg; it is an abbreviation for range). 配列。この接頭辞には標準的なひとつの型ではなく二つの型が続き、配列のもっとも一般的なケースを表す。数学的な観点から見ると、配列は配列内に格納された値にインデックスをマップする単純な関数である(そのため mp は map の略である)。mpxy という構造体の場合、x はインデックスの型であり、y は配列内に格納される値の型である。ほとんどの場合、重要なのは値の型であり、通常インデックスは整数で他の意味を持たない。この場合は rg が使用され、それは rgx が mpixx と等価であることを意味する(これは範囲(range)の略である風変わりな接頭辞 rg の説明でもある)。

訳注※:上記の「それは rgx が mpixx と等価」は、原文では「それは rgs が mpixx と等価(the rgs is equivalent to an mpixx)」となっています。
dn
an array. This is used in the rare case that the important part of the array mapping is the index, not the value. dn is an abbreviation for domain. Only a few of these are used in the entire Applications group; an example of a plausible use is given in the discussion of e, below. 配列。これは、配列の重要な部分が値ではなくインデックスであるような、まれなケースにおいて使用される。dn はドメイン(domain)の略である。アプリケーショングループ全体において、これらのほんのいくつかが使用される。有望な使用法の例は、下記の e の議論に示されている。
e
an element of an array. This is used in conjunction with a dn (and is thus just as rare); it is the type of the value stored in a dn. Just as rgx is equivalent to mpixx, dnx is equivalent to mpxex. An example of use is the native code generation part of the CS compiler; there is a type vr (an acronym for virtual register). A vr is just a simple integer, specifying which register to use for various pieces of code output. However, there is quite a bit more information than just a number that is associated with each register. This additional data is stored in a structure called an evr; there is an array of them called dnvr. Thus, the information for a given register can be found with the expression dnvr[vr]. 配列の要素。これは dn と共に使用され(したがって使用頻度は低い)、dn 内に保持される値の型である。rgx が mpixx と等価であるのと同様、dnx は mpxex と等価である。使用例は、型 vr (仮想レジスタ(virtual register)の頭字語)が存在する CS コンパイラのネイティブコード生成部である。vr は単なる整数であり、コード出力の様々な断片のために使用されるべきレジスタを特定する。しかしながら、各レジスタに関連する単なる数字以上の情報も相当にある。この追加情報は evr と呼ばれる構造体に保持され、dnvr と呼ばれるそれらの配列も存在する。したがって、ある特定のレジスタに関する情報は、dnvr[vr] という式で取得できる。
f
a bit within a type. This is a new prefix that is currently used only by a few projects, but is now the approved method for dealing with bits. It is typically used for overloading an integer type with one or more bit flags, in otherwise unused portions of the integer. This should not be confused with the f type, in which the entire value is used to contain the flag. An example is a scan mode (type sm), with possible values smForward and smBackwards. Since the basic mode only requires a few bits (in this case only one bit), the remainder of a word can be used to encode other information. One bit is used for fsmWrap, another for fsmCaseInsens. Here the f is a prefix to the sm type, specifying only a single bit is used. ある型の内部のビット。これは今のところ少数のプロジェクトで使用されている新しい接頭辞だが、現状ではビットを扱うために承認された方法である。一般にこれは、ひとつ以上のビットフラグを持つ整数型か、整数の未使用部分におけるオーバーロードに使用される。値全体にフラグを含む型 f とこれとを混同してはならない。一例は、取り得る値が smForward と smBackwards であるスキャンモード(scan mode)(型 sm)である。基本的なモードは少数のビット(この場合は 1 ビット)しか必要としないため、ワードの残りを別の情報の符号化に使用することができる。あるビットは fsmWrap に使用され、また別のビットは fsmCaseInsens に使用される。ここで f は型 sm への接頭辞であり、単一のビットだけが使用されていることを表す。
sh
a shift amount. This is another new prefix used to deal with bits within other types (complementing the "f" prefix); it specifies the location within the type by a bit number (rather than the bit mask which the "f" prefix specifies). It actually is followed by two types; the first type is the type being shifted (almost always an f), and the second type is the type the bits are stored within. Continuing the above example of scan modes, if fsmWrap has a value of 4000 hex, shfsmWrap would have the value of 14. シフト(shift)量。これは別の型の内部のビットを扱うために使用されるもうひとつの新しい接頭辞である(接頭辞 "f" を補完する)。これはその型の中での位置をビット数によって表す。実際はこの後に二つの型が続く。最初の型はシフトされる型(ほとんどの場合 f)であり、二つ目はそのビットが格納されている型である。先のスキャンモードの例を続けると、もし fsmWrap が 16 進の値 4000 を持つ場合、shfsmWrap は値 14 を持つことになる。
u
a union. This is a rarely used prefix; it is used for variables that can hold one of several types. In practice this becomes unwieldy. An example is a urwcol, which can hold either a rw type or a col type. ユニオン(union)。これはまれにしか使用されない接頭辞であり、複数の型のひとつを保持することのできる変数に使用される。実際にはこれは扱いにくいものになる。例 は urwcol で、型 rw または型 col のどちらかを保持することができる。
a
an allocation. This is a rarely used prefix; it is used to distinguish between an array and a pointer to it. Thus, sz is a pointer to a null-terminated string and asz is the actual allocated space. a is almost invariably used in conjunction with a pointer-type prefix, in order to allow the pointer to be explicit (rather than implicit, as with an sz). It is essentially the inverse of a p prefix, so pasz is equivalent to sz. Its best use is with the h prefix; hasz is a handle to a null-terminated string. Most of the current Applications code (incorrectly) omits the a. 割り当て(allocation)。これはまれにしか使用されない接頭辞であり、配列と配列へのポインタとを区別するために使用される。つまり、sz は null 終端文字列へのポインタであり、asz は実際に割り当てられた領域である。ポインタであることを(sz のように暗黙的にではなく)明示できるように、a はほとんど常にポインタ型の接頭辞と共に使用される。これは実質的に接頭辞 p の逆の意味である。そのため pasz は sz に等しい。これは接頭辞 h を伴なうのが最適な使用法であり、hasz はヌル終端文字列へのハンドルである。現在のほとんどのアプリケーションコードは、(誤って) a を省略している。
v
A global variable グローバル変数。

2.1.2.1. Some Examples 2.1.2.1. 例

Since the prefixes and base types both appear in lower case, with no separating punctuation, ambiguity can arise. Is pfc a tag of its own (e.g., for a private first class), or is it a pointer to an fc? Such questions can be answered only if one is familiar with the specific types used in a program. To avoid problems like this it is often wise to avoid creating base type names that begin with any of the common prefixes. In practice, ambiguity does not seem to be a problem. The idea of additional punctuation to remove the ambiguity has been shown to be impractical. 接頭辞と基本型とは共に小文字であり区切りがないため、不明確さが生じる。pfc はただのタグ(例えば上等兵(private first class))だろうか? それとも fc へのポインタだろうか? このような質問は、その人がプログラム内で使用される特有の型に精通している場合にのみ答えられる。この種の問題を避けるために、一般的な接頭辞と同じ文字から始まる基本型名を生成するのを避けるのが、しばしば賢明である。実際問題としては、不明確さが問題となるようには思えない。不明確さを取り除くために区切りを追加するという考え方は、非実用的であることが明らかとなっている。

The following list contains both common and rarer usages: 以下のリストは、一般的な使用法とまれな使用法とを含む:

pch
a pointer to a character. 文字(character)へのポインタ。
ich
an index into an array of character. 文字の配列内のインデックス。
rgst
an array of Pascal-type strings. Hungarian is not sufficient in itself to indicate whether this is an array of characters or an array of pointers; since strings are usually variable length, it is probably a safe bet that this is an array of pointers to the actual characters. パスカル形式の文字列の配列。ハンガリアン記法それ自体だけでは、それが文字の配列なのかポインタの配列なのかを表すのに不十分である。文字列はたいてい可変長であるため、これは実際の文字へのポインタの配列であるという安全な考え方である。
grst
a group of Pascal-type strings. As with the above example, this could be either an array of characters or of pointers; since it is a gr, not an rg, it is probably safe to assume that it is an array of characters. パスカル形式の文字列のグループ。上記の例と同様、これは文字またはポインタの、どちらかの配列である可能性がある。これは rg ではなく gr であるため、これは文字の配列であると仮定するのが 安全だろう。
bst
an offset to a particular Pascal-type string in a grst. grst 内の特定のパスカル形式文字列へのオフセット。
phpx
a near pointer to a huge pointer to an object of type x. 型 x のオブジェクトへの huge ポインタへの near ポインタ。
pich
a near pointer to an index into a character array. A common use for something like this is passing a pointer as a parameter to a function so that a return value can be stored through the pointer; pich would be extremely unlikely to be used in an expression without indirection (pich+=2 is probably gibberish; (*pich)+=2 may well be meaningful). 文字の配列内へのインデックスへのポインタ。一般的な使用法は関数への引数としてポインタを渡し、そのポインタを通して値を保存して返す場合である。pich が式の中で間接指定なしに使用されることは、まずありえないだろう(pich+=2 はおそらく無意味であり、(*pich)+=2 が重要だろう)。
en
probably a base type (such as an entry). Conceivably it is an element for an array indexed by an n; only knowledge of the application can tell for certain. 恐らく基本型(例えばエントリー(entry))。あるいは、n によってインデックスされる配列の要素かもしれない。アプリケーションの知識だけが確実な答えを教えられる。
hrgn
handle to a r region. Again there is ambiguity; this could be interpreted as a handle to an array of n's or a huge pointer to an array of n's. リージョン(region)へのハンドル。ここにも不明確さがある。これは n の配列へのハンドルとして、または n の配列への huge ポインタとして解釈され得る。
dx
length of a horizontal line (difference between x coordinates). 水平線の長さ(x 座標間の差異)。
rgrgx
a two-dimensional array of x's (an array of arrays of x's). x の二次元配列(x の配列の配列)。
mpminpfn
an array of pointers to functions, indexed by mi's. For example, an mi could be a menu item, and this array could be used for a command dispatch. Again, context makes the parsing clear; this could equally well be interpreted as an array of fn's (perhaps friendly nukes), indexed by mip's (perhaps missile placements). 関数へのポインタの配列で、mi でインデックスされる。例えば、mi はメニュー項目(menu item)であり、この配列はコマンドディスパッチのために使用されるのかもしれない。ここでもコンテキストが解析を明確にする。これは fn (例えば味方の核(friendly nuke))の配列であり、mip (おそらく、ミサイルの位置(missile placements))によってインデックスされるものとしても解釈される。
pv
pointer to a void. Could be used as an argument to Free. void へのポインタ。Free への引数として使用できる。
hrgch
huge pointer to an array of characters. Could instead be interpreted as a handle to an array of characters, depending on the application. 文字の配列への huge ポインタ。アプリケーションに依存して、文字の配列へのハンドルとしても解釈できる。

2.1.3. Qualifiers 2.1.3. 限定子

While the prefixes and base type are sufficient to fully specify the type of a variable, this may not be sufficient to distinguish the variable. If there are two variables of the same type within the same context, further specification is required to disambiguate. This is done with qualifiers. A qualifier is a short descriptive word (or facsimile; good English is not required) that indicates what the variable is used for. In some cases, multiple words may be used. Some distinctive punctuation should be used to separate the qualifier from the type; in C and other languages that support it, this is done by making the first letter of the qualifier upper-case. (If multiple words are used, the first letter of each should be upper-case; the remainder of the name, both type and qualifier always lower-case. There is one special case to watch out for; defined constants specifying the size of a type are often of the form cbFOO or cwFOO, where foo is the type. Strictly speaking only the F in FOO should be capitalized, but the incorrect usage is fairly common.) 接頭辞と基本型とは変数の型を完全に表すのに十分である一方、変数を区別するには十分ではないだろう。同じコンテキスト内に同じ型の二つの変数があるとき、あいまいさをなくすためには更なる指定が必要である。これは限定子で実現される。限定子は短い説明的な単語(または模写で、正しい英語である必要はない)であり、その変数が何に使用されるかを表す。場合によっては複数の単語を使用してもよい。型と限定子とを区切るために、何らかの区切りを使用するべきである。C やそれをサポートする他の言語では、限定子の最初の 1 文字を大文字にし、型と限定子の名前の残りを常に小文字にすることで実現される。(複数の単語を使用する場合、各単語の最初の文字を大文字にし、型と限定子の名前の残りを常に小文字にするべきである。注意するべき特別なケースがひとつある。型のサイズを表す定数の定義は、しばしば cbFOO または cwFOO となる(foo が型である)。厳密に言えば FOO の中の F のみを大文字にするべきだが、この間違った使用法が極めて一般的になっている。)

Exactly what constitutes a naming context is language specific; within C the contexts are individual blocks (compound statements), procedures, data structures (for naming fields), or the entire program (globals). As a matter of good programming style, it is not recommended that hiding of names be used; this means that any context should be considered to include all of its subcontexts. (In other words, don't give a local the same name as a global.) If there is no conflict within a given context (only one variable of a given type), it is not necessary to use a qualifier; the type alone serves to identify the variable. In small contexts (data structures or small procedures), a qualifier should not be used except in case of conflict; in larger contexts it is often a good idea to use a qualifier even when not necessary, since later modification of the code may make it necessary. In cases of ambiguity, one of the varibles may be left with no qualifier; this should only be done if it is clearly more important than the other variables of the same type (no qualifier implies primary usage). 名前付けコンテキストを構成するものが厳密に何であるかは、言語に固有のものとなる。C 言語では、コンテキストは個々のブロック(複合文)、手続き、データ構造(名前を持つフィールドのため)、プログラム全体(グローバル)である。優れたプログラミングスタイルとして、名前の隠蔽は推奨されない。つまり、任意のコンテキストはそのすべてのサブコンテキストを含むと考えるべきであることを意味する。(言い換えると、グローバルと同じ名前をローカルに与えるべきではない。) ある特定のコンテキスト内で衝突がなければ(ある型の変数がひとつだけなら)、限定子を使う必要はなく、型だけで変数を表す。小さいコンテキスト(データ構造または小さい手続き)内では、衝突する場合を除いて限定子を使用するべきではない。より大きいコンテキストでは、後のコードの修正がそれを必要とするため、必要でなくとも限定子を使用するべきである。あいまいな場合、変数のひとつを限定子なしのまま残してもよいが、これはその変数が同じ型の他の変数に比べて明らかに重要な場合にのみ行われるべきである(どんな限定子も主な用法を暗示しない)。

Since many uses of variables fall into the same basic categories, there are several standard qualifiers. If applicable, one of these should be used, since they specify meaning with no chance of confusion. In the case of multiple word qualifiers, the order of the words is not crucial, and should be chosen for clarity; if one of the words is a standard qualifier, it should probably come last (unfortunately, this suggestion is by no means uniformly followed). The standard qualifiers are: 多くの変数の使用法は同じ基本的なカテゴリーに分類されるため、いくつかの標準的な限定子が存在する。混乱なく意味を表せるように、適用可能であれば、これらのひとつを使用するべきである。複数の単語による限定子の場合、単語の順序は重要ではなく、明確性のために選択されるべきである。単語のひとつが標準限定子であれば、それを最後に置いたほうがよい(残念ながらこの提案は、決して一様に従うものではない)。標準限定子は以下の通り:

First
the first element in a set. This is usually used with an index or a pointer (e.g., pchFirst), referring to the first element of an array to be dealt with. The index may be an implied index (as with a rw type in a spreadsheet). 集合内の最初(first)の要素。これは一般にインデックスまたはポインタと共に使用され(例えば pchFirst)、配列内の先頭として扱われるべき要素を参照する。インデックスは暗黙のインデックスであってもよい(スプレッドシートにおける rw 型の場合と同様)。
Last
the last element in a set. This is usually used with an index or a pointer (e.g., pchLast), referring to the last element of an array to be dealt with). Both First and Last represent valid values (compare with Lim below); they are often paired, as in this common loop: 集合内の最後(last)の要素。これは一般にインデックスまたはポインタと共に使用され(例えば pchLast)、配列内の最後として扱われるべき要素を参照する。First および Last は(後述の Lim とは対照的に)有効な値を表し、しばしば以下のような一般的なループ処理において対で使用される:
 for(ich=ichFirst; ich<=ichLast; ich++)
Lim
the upper limit of elements in a set. This is not a valid value; for all valid values f x, x<xLim. xLim is equivalent to xLast+1; xLimxFirst is the dx which specifies the number of elements in the set. Thus, the following code is typical (cp is a type that is an implied index): 集合内の要素の上限(upper limit)。これは有効な値ではなく、有効なすべての値 x は、x<xLim である。xLim は xLast+1 に等く、xLimxFirst は集合内の要素数を表す dx である。したがって、以下のコードが一般的である(cp は暗黙のインデックスである型である):
 for (cp=cpFirst,cpLim=cpFirst+dcp; cp<cpLim; cp++)
Min
the first element in a set. This is very similar to First, but typically refers to the actual first element of an array, not just the first to be dealt with. It is also more often used with a pointer than an index, since ixMin tends to be 0. 集合内の最初の要素。これは First によく似ているが、一般に最初に扱われるべき要素ではなく、配列の本当の先頭要素を参照する。またこれは、ixMin が 0 になる傾向があるため、しばしばインデックスよりポインタと共に使用される。
Max
the upper limit of elements in a set. This is not a valid value; for all valid values of x, x<xMax. Max is typically used for compile-time constants, or variables that are set a load time and not changed. Very often, ixMax is used to specify the number of elements in an rgx array. 集合内の要素の上限。これは有効な値ではなく、有効なすべての値 x は、x<xMax である。一般に Max は、コンパイル時定数、またはロード時に設定され変化しない変数に使用される。ixMax は、rgx 配列内の要素数を表すために頻繁に使用される。
Mac
the current upper limit of elements in a set. This is very similar to Max, but is used where the upper limit varies over time (such as for a variable length structure, or a growing heap). This is not a valid value; it is often paired with Min, as in this common loop: 集合内の要素の現在(current)の上限。これは Max によく似ているが、時間とともに変化する(例えば可変長構造体や、増加するヒープなどの)上限に使用される。これは有効な値ではなく、以下のような一般的なループ処理において、Min と対で使用される:
   for(pch=pchMin; pch<pchMac; pch++)
  訳注※:上記のコードサンプルは原文では以下のようになっています。

  for(pch=pchMin; pch)
Mic
the current first element in a set. This is very similar to Min, but is used where the low value varies over time (such as for a heap that grows downward in memory). Like Min, this is a valid value. Since few things grow downward, this is not often used. 集合内の現在(current)の先頭要素。これは Min によく似ているが、時間とともに変化する(例えばメモリ内で減少するヒープのための)下限値に使用される。Min と同じく、これは有効な値である。減少するものは少ないため、これはあまり頻繁には使用されない。
Most
the last element in a set. Identical to Last, but used when paired with a Min. Can also be viewed as Mac-1. This is a new addition to the standard, and is thus not yet much used. Typical usage would be: 集合内の最終要素。Last とまったく等価だが、Min と対になる場合に使用される。Max-1 と見なすこともできる。これは最近標準に追加されたものであり、そのためまだそれほど使用されていない。典型的な使用法は以下のようになるだろう:
  for (pch=pchMin; pch<=pchMost; pch++)

Note that the above qualifiers have a strict relationship: 上記の限定子は、以下のような厳密な関係を持つことに注意してほしい:

Min<=Mic<=First<=Last<=Most<Lim<=Mac<=Max
Sav
a temporary saved value. Often used as part of error recovery, or just when temporarily modifying variables that need to be restored. Typical usages include: 一時的に保存される値。エラーリカバリーの一部として、または元の状態に戻す必要のある変数を一時的に変更する場合に使用される。典型的な使用法は以下の通り:
 envSav=envMem;
 if (SetJmp(&envMem))
   ...
 envMem=envSav;

 rwSav=rwAct;
 for (rwAct=rwFirst; rwAct<=rwLast; rwAct++)
   ...
 rwAct=rwSav;
 訳注※:上記のコードサンプルは原文では以下のようになっています。

 envSav=envMem;
 if (SetJmp(&envMem))
 
 
 envMem=envSav;
 rwSav=rwAct;
 for (rwAct=rwFirst; rwAct<=rwLast; rwAct++)
 
 rwAct=rwSav;
Nil
a special illegal value. Typically used with defined constants, this is a value that can be distinguished from all legal values. This is often 0 or -1, but may be something else in some circumstances. 特別な不正値。一般に定義済み定数と共に使用され、あらゆる有効な値と区別できる値である。これはしばしば 0 または -1 であるが、環境によっては別の値でもよい。
Null
the 0 value. Typically used with defined constants, this value is always 0, typically an illegal value. May or may not be equivalent to Nil. In order to avoid confusion, it is usually best not to have both Nil and Null defined; if both do exist, the differences should be clearly delineated. 値 0。一般に定義済み定数と共に使用され、値は常に 0 であり、一般に不正な値である。Nil と等しくても、違っていてもよい。混乱を避けるために、Nil と Null とを両方とも定義しないことが最善である。両方を混在させる場合、その違いを明確に線引きするべきである。
T
a temporary value. This is often convenient to distinguish the second value in a given context. However, unless it is a truly temporary usage, it is often better to use a more descriptive qualifier. (After all, what happens when you add the third variable of the same type). Some particularly poor usages stack the T's up, to produce variables such as pchTT or pchT1; this is almost certainly an indicator that better qualifiers should be used. 一時的(temporary)な値。これはしばしば、ある特定のコンテキスト内の第二の値を区別するのに便利である。しかしながら本当に一時的な使用ではない限り、もっと説明的な限定子を使用するのが望ましい。(結局のところ、同じ型の第三の変数を追加するときに起こることである。) 特によくない使い方は、pchTT や pchT1 などの変数を作り、T を積み上げていくことである。これはほぼ確実に、よりよい限定子が使用されるべき兆候である。
Src
a source. Typically paired with Dest and used in transfer operations. 送信元(source)。一般に Dest と対になり、転送操作において使用される。
Dest
a destination. Typically paired with Src and used in transfer operations. 宛先(destination)。一般に Src と対になり、転送操作において使用される。

2.1.4. Structure Members 2.1.4. 構造体のメンバー

When possible, structure members are named the same way variables are. Since the context is small (only the structure), conflicts are less likely, and qualifiers are often neither needed nor used. If the language does not support separate contexts for each structure (e.g., masm), the structure name is appended to the member as a qualifier. Thus, the following declarations are equivalent (the one on the left is for C, the one on the right for masm): 可能であれば、構造体メンバーは変数と同じ方法で命名されるべきである。コンテキストが小さい(構造体のみである)ため、衝突はそれほど起こりそうになく、限定子はしばしば不要であり、使用されない。各構造体のコンテキストの分離を言語がサポートしない場合(例えば masm の場合)、限定子として構造体名をメンバーに付加する。したがって、以下の宣言は等価である(左側は C 言語向け、右側は masm 向け):

 typedef struct FOO
 struc {
     char    *pch;        pchFoo  dw     ?
     int     w;           wFoo    dw     ?
     char    rgch[10];    rgchFoo db     10 dup (?)
 } FOO;

  訳注※:上記のコードサンプルは原文では以下のようになっています。

  typedef struct FOO
  struc {
          pchFoo  dw      ?
          char    *pch;
          wFoo    dw      ?
          int     w;
          rgchFoo db      10
          dup(?)
  } FOO;

In some cases, one type is a special instance of another type. When this is the case, the special instance names should consist of the base instance name plus a character. For example, in Word there is a base type of CHR (character run); special instances are CHRF (formula character run), CHRT (tab character run), and CHRV (vanished character run). 場合によっては、ある型が別の型の特化インスタンスである。その場合、その特化インスタンスの名前は、基本インスタンスに 1 文字を加えて構成されるべきである。例えば、Word 内に CHR (character run)の基本型が存在する場合の特化インスタンスは、CHRF (formula character run)、CHRT (tab character run)、CHRV (vanished character run)などとなる。

2.2. PROCEDURES 2.2. 手続き

Unfortunately, the simple rules used for variable names do not work as well for procedures. Whereas the type of a variable is always quite important, specifying how that variable may be used, the important part of a procedure is typically what it does; this is especially true for procedures that don't return a value. In addition, the context for procedures is usually the entire program, so there is more chance for conflict. To handle these issues, a few modifications are made to the simple rules: 残念ながら、変数名に使用される単純な規則は手続きではうまく機能しない。変数の型はその変数がどのように使用されるかを特定することで常に非常に重要である一方、手続きにおいて重要な部分は、それが何をするのかである。これは特に値を返さない手続きにあてはまる。さらに、手続きのコンテキストは通常プログラム全体であるため、衝突の可能性もより高くなる。これらの問題を扱うために、単純な規則に少し変更を加える:

  1. All procedure names are distinguished from variable names by the use of some standard punctuation; in C this is done by capitalizing the first letter of the procedure name (all variable names begin with a lower case type). すべての手続き名は、何らかの標準的な区切り方法を使用することで変数名と区別される。C 言語では、手続き名の先頭の文字を大文字にすることで行われる(すべての変数名は小文字から始まる)。
  2. If the procedure returns a value (explicitly, not implicitly through pointer parameters), the procedure name begins with the type of the value returned; if no value is returned, the name must not begin with a valid type. 手続きが(明示的に、またはポインタ引数を通して暗黙的に)値を返す場合、手続き名は返される値の型で始まり、値を返さない場合、名前は有効な型で始まってはならない。
  3. If the procedure is a true function (operating mainly on its parameters and returning a value, with few or no side effects), it is standard to name the procedure AFromBCD..., where A is the type of the value returned, and B, C, D, etc. are the types of the objects referred to by the parameters. In some cases, the types are exactly the types of the parameters (e.g., CmFromIn(in) would convert inches to centimeters). In other cases, the types are the base types of the parameters (e.g., DxFromWnd(pwnd) could be used to obtain the width of a window). Some projects always use the full parameter type (the previous example would be DxFromPwnd(pwnd)). Both methods (full type and base type) are accepted. As another simple example, returning the binary value of an ASCII string would be done by a procedure called WFromSt (equivalent to the standard C atoi). 手続きが本当の関数(主にその引数に基づいて動作して値を返し、副作用をほとんど、またはまったく持たない)である場合、その手続きを AFromBCD... と命名するのが標準的である。ここで A は返される値の型であり、B・C・D 等は引数によって参照されるオブジェクトの型である。場合によっては、この型はまさしく引数の型になる(例えば CmFromIn(in) は、インチ(inches)をセンチ(centimeters)に変換するだろう)。そうでない場合、この型は引数の基本型になる(例えば DxFromWnd(pwnd) は、ウィンドウ(window)の幅を取得するために使用されるだろう)。一部のプロジェクトは完全な引数の型を使用する(先の例は DxFromPwnd(pwnd) になるだろう)。両方の手法(完全な型と基本型)が受け入れられる。別の単純な例だと、ASCII 文字列のバイナリ値を返す場合、手続き名は WFromSt となる(C 言語の atoi に相当する)。
  4. If the procedure is not a true function, follow the type (if any) with a few words describing what the procedure does (a verb followed by an object is usually good). Each word should be capitalized. If the type of a parameter is important, it may be appended as well; in many cases this is unnecessary, and may even be confusing (if the type is not truly important). 手続きが関数ではない場合、その手続きが何をするのかを説明する少数の単語に型が続く(一般に動詞の後にオブジェクトを続けるのが優れている)。各単語はキャピタライズされるべきである。引数の型が重要な場合にはそれも付加されてよいが、多くの場合それは不要であり、(もし型が本当は重要でなければ)混乱を招く可能性さえある。
  5. If the procedure operates on an object, the type of the object should be appended to the name; as in 3), this may be different than the types of the parameters, though it is probably related in some manner. Procedures like this are commonly used when programming in a class-like (or object-oriented) manner; typically the first parameter to such a procedure is a pointer to the object to be manipulated. For example, you could have procedures like InitCa(pca, ...), InitDd(pdd, ...), etc. 手続きがオブジェクトを扱う場合、3 の場合と同様に、そのオブジェクトの型を名前に付加するべきである。恐らく何らかの方法で関連付けられるとしても、これは引数の型とは異なるかもしれない。このような手続きは、一般にクラスライク(またはオブジェクト指向)のプログラミング時に使用され、一般にそのような手続きへの最初の引数は、処理されるべきオブジェクトへのポインタである。例えば、InitCa(pca, ...)、InitDd(pdd, ...) などの手続きを持つことができるだろう。

2.2.1. Macros 2.2.1. マクロ

Macros should be handled exactly the same way as procedures; for historical reasons, you may find some macros that do not follow the correct rules (e.g., min, bltbyte). マクロは手続きとまったく同じ方法で扱われるべきである。歴史的な理由により、正しい規則に従わないマクロを見つけることがあるかもしれない(例えば min、bltbyte)。

2.2.2. Labels 2.2.2. ラベル

Labels can be considered to be a variant on procedures; they are after all effectively identifiers specifying a chunk of code. Within C, they are named similarly to procedures; they obviously neither return a value nor take parameters, so no types are specified. The first letter is upper case, and the name itself is just a few words specifying the condition that causes the label to be reached (either by falling through, or via a goto). Since the context of a label is limited to its procedure, these can be pretty generic terms; typical examples are GotErr, OutOfMem, LoopDone. ラベルは手続きの変化形であると考えられる。結局のところ、ラベルはコードのかたまりを特定する識別子である。C 言語の場合、その名前は手続きに似ており、値を返さず引数も取らないため、型は特定されない。最初の文字は大文字であり、名前自身はそのラベルに到達する条件(条件不成立か、goto によってか)を表す小数の単語だけである。ラベルのコンテキストはその手続き内に限られるため、ごく一般的な名前を採用することができる。典型的な例は、GotErr、OutOfMem、LoopDone などである。

Within assembly, labels are somewhat trickier. First off, there are many more labels used. Second, depending on the assembler, all labels may have global (or at least filewide) context. To deal with these constraints, the rules may be modified somewhat. For labels that are inserted solely because of assembler constraints (i.e., jumps corresponding to high level control flow constructs), temporary labels should be used. If the assembler supports true temporary labels (valid only within the current procedure, or up to the next global label), they should be used, in ascending numeric order. If true temporary labels are not available, the most common convention is to use the initials of the procedure, followed by a number, in ascending order. Of course, gaps should be left between numbers to facilitate later modification (initially setting to multiples of 10 works well). This is far from perfect, and can create conflicts between procedures that have the same initials; some people prefer to give all labels, temporary or not, full English names for clarity. For labels that correspond to true C labels, C conventions can be used; to avoid conflict, it is often useful to prefix with the procedure initials. アセンブリ言語の場合、ラベルは少々扱いにくい。第一に、ずっと多くのラベルが使用される。第二に、アセンブラによってはすべてのラベルがグローバル(または少なくともファイル全体)のコンテキストを持つ可能性がある。これらの制約を扱うために、規則をいくらか変更してよい。アセンブラの制約だけのために挿入されるラベル(つまり上位レベルの制御フロー構造)の場合、一時ラベルを使用するべきである。アセンブラが本当の一時ラベル(現在の手続き内のみ、または次のグローバルラベルまで有効)をサポートする場合、それを番号順に使用するべきである。本当の一時ラベルを利用できない場合、もっとも一般的な習慣は、その手続きの頭文字に続けて昇順の番号を使用することである。当然ながら、後の修正を手助けするために、各数字の間には間隔を空けておくべきである(初期値としては 10 の倍数がよいだろう)。これは完璧にはほど遠く、同じ頭文字を持つ手続き間での衝突を生じうる。一部の人々は明確性のために、すべてのラベル(一時ラベルであろうとなかろうと)に完全な英語名を与えることを好む。真の C 言語のラベルに対応するラベルの場合、C 言語の慣例を使用できる。衝突を避けるために、手続きの頭文字を前に置くのがしばしば好都合である。

2.3. DEFINED CONSTANTS 2.3. 定義済み定数

As much as possible, defined constants should look just like variables of the same type. For many types, defined constants will exist for the Nil, Max, Min, and/or Last values. The program text will read exactly as if they are variables. There are three common exceptions, all originating in the mists of time, and unlikely to change soon. NULL is defined to be 0, and is used with all pointer types; TRUE and FALSE are defined to be 1 and 0, and are used with f types (correct Hungarian, practiced by some projects uses fTrue and fFalse instead of TRUE and FALSE). 定義済み定数は出来るだけ同じ型の変数と同じように見えるべきである。多くの型に対して Nil・Max・Min・Last のための定義済み定数値が存在するだろう。プログラムは、それらが変数であるかのように読めるだろう。長い年月の間に考え出され、すぐに変更されそうにない三つの一般的な例外がある。NULL は 0 と定義されるべきであり、すべてのポインタ型と共に使用される。TRUE および FALSE は 1 および 0 と定義されるべきであり、型 f と共に使用される(一部のプロジェクトによって実践される正しいハンガリアン記法では、TRUE および FALSE の代わりに fTrue および fFalse が使用される)。

There are often types for which each value is a defined constant; these are essentially equivalent to enumeration types supported by some languages (including some variations of C). These are typically types used for table-drive algorithms, for specifying options to a procedure, or specifying possible return values. Note that these types are in fact separate types; they are not all examples of the same type, nor are they values for the w type. Since they are special purpose (you can't pass an option for procedure x to procedure y with any meaning), they must be a new type. You can of course use your own method to name these types; it is often convenient to just use the initials of the procedure that takes or returns the type (watching out for conflicts). since they are type quantities, the type must be present in the names; possible values for colors are not RED, BLUE, YELLOW, GREEN, BLACK, etc., but rather could be coRed, coBlue, coYellow, coGreen, coBlack, etc. しばしば、各値が定義済み定数である型が存在する。これらは基本的に、一部の言語でサポートされる列挙型(いくつかの C 言語の変化形を含む)に等しい。一般にこれらはテーブル駆動のアルゴリズムのために使用され、手続きへのオプションを指定したり、可能な戻り値を特定したりする。これらの型が実際には個別の型であることに注意してほしい。それらはすべて同じ型の例であるとは限らず、また型 w のための値でもない。それらは特殊用途である(どのような方法でも、手続き x のためのオプションを手続き y に渡すことはできない)ため、それらは新しい型でなければならない。もちろん、これらの型を命名するために独自の方法を使用することもできる。その型を受け取るか返すかする手続きの頭文字を(衝突に注意しながら)使用するのが、しばしば好都合である。これらは型量子(type quantities)であるため、その型は名前によって表されなければならない。色(colors)のために取り得る値は、RED、BLUE、YELLOW、GREEN、BLACK などではなく、coRed、coBlue、coYellow、coGreen、coBlack などとなる。

2.4. STRUCTURES 2.4. 構造体

Each structure is almost by definition its own type, and should be names as a type (two or three letters with some possible mnemonic value). By convention in C, the entire type name is capitalized in the definition of the type. The same rules apply to unions. Many of the projects find it convenient to include typedef's for each structure type; this means that the word struct is not included in declarations, and allows the redefinition of the type to an array, or even a simple type, without having to change all the declarations. Typedef's may also be suitable for non-structure types, particularly any that are not simple int's. 各構造体の大部分は定義上それ自身の型であり、型としての名前(2 文字または 3 文字に、いくつかのニーモニック値を伴なう)であるべきである。C 言語における慣例によって、型の定義において型名全体がキャピタライズされる。ユニオン(union)にも同じ規則が適用される。多くのプロジェクトが、各構造体のための typedef による型定義を含めるのが好都合であることを見出している。これは struct という単語を定義に含めないことを意味し、すべての定義を変更することなく、型を配列または単純な型へ再定義することを可能にする。typedef は、特に単純な int ではない非構造体の型にも適用可能だろう。

3. ADVANTAGES OF HUNGARIAN 3. ハンガリアン記法の利点

Before adopting a set of conventions, there are always two questions that must be answered: 規約を適用する前に、答えなければならない二つの質問がある:

The two questions are actually very closely related; answering the first will usually give an answer to the second, since knowing the goals allows one to see how closely a solution will meet the goals. For naming conventions, many of the goals are well-known, if not often formalized; most good programmers already attempt to meet the goals in a variety of ways. この二つの質問は実際には密接に関連している。目標を知ることで解決策がどれだけ綿密に目標を達成するするかを知ることができるため、通常、最初の質問の答えが第二の質問への答えになるだろう。命名規約の場合、形式化されていないとしても目標の多くはよく知られており、優れたプログラマはすでに様々な方法でその目標を達成しようと試みている。

3.1. MNEMONIC VALUE 3.1. ニーモニック値

An important need in naming objects in a program is the ability to remember what the name is, so that when the objects used, the programmer can quickly determine the name (which is the only way it can be used). Traditionally, this need has been met by using descriptive names for variables; for a given programmer working continually on a given program this is usually adequate. Problems arise, however, when a different programmer works on the project, or when the same programmer returns after a hiatus. What was once descriptive now has to be relearned. Hungarian helps somewhat in this respect, though it is not complete. The first part of a variable name can always be determined with no effort (it is the type), and if it is a standard use, the qualifier can also be determined (since it is one of the standard qualifiers). Non-standard qualifiers and procedure names can not be immediately determined; however, the situation is certainly no worse than the traditional situation, since the qualifier or procedure name has as much descriptive value as a traditional name. Furthermore, since there are fewer names that must be remembered (since one need not remember the standard ones), it is easier to remember them. プログラム内のオブジェクトを命名する際に重要な要求は、その名前が何であるかを思い出させる能力であり、それによりオブジェクトが使用されるとき、プログラマはその名前をすばやく判断できる(これがそれを使用できる唯一の方法である)。伝統的にこの必要性は、変数に説明的な名前を使用することで達成されてきた。ある特定のプログラムに関してある特定のプログラマが続けて作業する場合、一般にこれは適切である。しかしながら、そのプロジェクトで別のプログラマが作業する場合や、同じプログラマが休みのあとに戻ってきた場合に問題が起こる。説明的につけられた名前を再び学習しなければならない。完全ではないが、ハンガリアン記法はこの点で多少の手助けとなる。変数の最初の部分は常に労力なく判断できる(それは型である)上、もしそれが標準的な使用法であれば、限定子も決定する(標準限定子のひとつであるため)。非標準の限定子と手続き名とは、すぐに判断することができない。しかしながら、この限定子および手続きの名前は伝統的な名前よりも説明的な値を持つため、その状況は伝統的な状況よりもひどいものではない。さらに、覚えなければならない名前がより少なくなる(標準的な名前を覚える必要がない)ため、思い出すのはより簡単である。

3.2. SUGGESTIVE VALUE 3.2. 示唆的な値

At least as important as being able to go from an object to a name (the mnemonic value) is the ability to go from a name to an object (the suggestive value). This is most important when reading code written by someone else; this affects almost all programs today, either because multiple people are working on them, or because they are outgrowths of earlier programs. Again, the traditional approach has been to use names descriptive in some manner; Hungarian again improves the situation somewhat. For the relatively small cost of learning the types used in a given program, a reader gains a much better understanding of what the program does, since the types used in a statement often help determine the meaning of the statement. This is enhanced even more by the use of standard qualifiers; again, the non-standard qualifiers are at least as clear as the traditional names. オブジェクトから名前にたどり着けること(記憶を助ける値)と少なくとも同じくらいに重要なことは、名前からオブジェクトにたどり着けること(示唆的な値)である。これは他人の書いたコードを読む場合にもっとも重要なことである。プログラムに関して複数の人が作業しているため、またはそれが過去のプログラムの副産物であるため、これは今日のほとんどすべてのプログラムに影響する。さらに、伝統的なアプローチは何らかの方法で説明的な名前を使用してきたが、ハンガリアン記法はその状況を多少なりとも改善する。ステートメント内で使用される型はしばしばそのステートメントの意味を判断する手助けとなるため、ある特定のプログラム内で使用される型を学習するという比較的小さいコストで、読み手はそのプログラムが何をするのかをよりよく理解することができる。これは標準限定子の使用によりさらに高められる。一方で非標準の限定子は、少なくとも伝統的な名前と同程度には明確である。

3.3. CONSISTENCY 3.3. 一貫性

Partially an aesthetic idea ("the code looks better"), this is also an important concept for the readability of code. Just as Americans often have an extremely difficult job following the action of Russian novels, since the same character goes by many different names, a programmer will have a difficult time understanding code in which the same object is referred to in unrelated ways. Similarly, it is confusing to find the same name referring to unrelated objects. This is a serious problem in traditional contexts, since English is a rich enough language to have many terms that roughly describe the same concept, and also terms that can describe multiple concepts. This problem is exacerbated when programmers resolve name conflicts by use of abbreviations, variant spellings, or homonyms; all of these methods are prone to accidental misuse, through typographical errors or simple failure to understand subtle differences. Hungarian resolves this problem by the use of detailed rules; since all names are created using the same rules, they are consistent in usage. ある程度は感性の問題("コードがきれいに見える(the code looks better)")だが、これもコードの信頼性のための重要な概念である。アメリカ人がロシアの小説の筋を追うは、同じキャラクターが多くの異なる名前で通っているため多くの場合非常に困難な作業であるように、同じオブジェクトが関係のない方法で参照されるコードを理解するのにプログラマは苦労するだろう。同様に、同じ名前が無関係なオブジェクトを参照していることが分かると混乱する。英語は同じ概念を大雑把に説明する多くの用語と複数の概念を説明できる用語とを持つ十分に豊かな言語であるため、これは伝統的な状況において深刻な問題である。プログラマが略語や異なるスペルや同音異義語を使用して名前の衝突を解決すると、この問題は悪化する。これらの方法はすべて、微妙に異なって理解される誤字や単純な間違いにより、思いがけない誤用を招く傾向がある。ハンガリアン記法は詳細な規則を使用することでこの問題を解決する。すべての名前が同じ規則を使用して生成されるため、それらの用法が一貫しているためである。

3.4. SPEED 3.4. スピード

It is desirable to minimize the amount of time spent on determining names; in a sense this is wasted time, since getting the "right" name doesn't improve the program's efficiency or functionality. Since the traditional naming methods rely on good descriptions to meet the above goals, a programmer has to spend a goodly amount of time to in fact invent good descriptions; speedy name decisions are likely to result in unmnemonic, unsuggestive, or inconsistent names. In Hungarian, on the other hand, only a few name the same names, everyone's code will be similar, and therefore easy to read and modify. Traditional naming schemes are extremely unlikely to reach this goal, since English has far too many ambiguities to expect different individuals to describe things in identical terms. It would be naive to expect that Hungarian will cause all programmers to write code identically, or even to use identical names. The names are likely to be much more similar, however, since they are composed using the same rules, with the same types and standard qualifiers. 名前を決定するのに費やす時間を最小化するのが望ましい。"正しい(right)" 名前を得ることがそのプログラムの効率や機能性を改善するわけではないため、ある意味でそれは時間の無駄である。上記の目標を達成するのに伝統的な命名方法は優れた説明に依存するため、プログラマは優れた説明を発明するために多くの時間を費やさなければならない。拙速な名前の決定は、記憶を助けず、示唆的でなく、また一貫性のない名前を生じる可能性がある。一方でハンガリアン記法では、ごく少数が同じ名前を挙げるため、誰のコードでも似たようなものになり、したがって読みやすく、修正しやすいものとなる。異なる個人が同一の用語でものごとを説明すると期待するには英語はあいまいすぎるため、伝統的な命名方法はこの目標にまったく到達しそうにない。ハンガリアン記法によりすべてのプログラマが同一のコードを書くだろうと期待したり、同一の名前を使用すると期待したりするのは認識が甘いだろう。しかしながら、それらの名前は同じ型と標準限定子とを用いて同じ規則を使用して組み立てられるため、より似たものになるだろう。

4. CONCLUSION 4. 結論

Hungarian is a useful set of rules used to determine the names used in a program. There is no denying that it takes a little time to become familiar with it; true enlightenment comes only with effort. We strongly believe the results are worth the effort. The Applications Development group has been using Hungarian since its inception in 1981, and people at Xerox PARC were using it even earlier. The consistent use of Hungarian makes the programmer's job easier; it is both easier to write in Hungarian (there are fewer superfluous choices to make) and easier to read and modify existing code. The set of conventions is sufficient to deal with most current situations by itself; it has also proven adaptable to changes in the programming environment. Perhaps the best testimonial for Hungarian is the fact that a number of programmers have continued to use Hungarian even after leaving the jobs in which they encountered it; they have felt that the advantages were great enough to warrant the effort necessary to promote its use elsewhere. We hope that you will feel this way as well, once you become familiar with Hungarian's usage. ハンガリアン記法は、プログラム内で使用される名前を決定するために使用される実用的な規則である。ハンガリアン記法に精通するのに少しばかり時間が掛かることは否定できない。真の啓蒙は努力と共にのみある。これに努力の価値があることを私たちは強く信じている。アプリケーション開発グループは 1981 年の始めからハンガリアン記法を使用してきた。また Xerox PARC は、さらに以前から使用していた。ハンガリアン記法の一貫した使用はプログラマの仕事を簡単にする。ハンガリアン記法で書くことも簡単(為すべき余分な選択肢は少ない)であり、既存のコードを読んだり修正したりするのも簡単になる。この規約は、それ自体で現状の大部分を扱うのに十分である。プログラミング環境の変化に適応できることも証明されている。ハンガリアン記法に対する最大の証明は、多くのプログラマが、たずさわった仕事を離れた後でもハンガリアン記法を使い続けているという事実である。彼らは別の場所でハンガリアン記法の使用を勧めるのに必要な努力を正当化するに十分な利点を感じたのである。ハンガリアン記法の使用法に精通すれば、あなたも同じような気持ちになることを私たちは願っている。

REVISION HISTORY (改訂履歴)

Date    Action

09/04/87  Original (DBK)

09/15/87  Moved to word; added some rarer types and pre-
      fixes and cleaned up other definitions in
      response to feedback. (DBK)

01/18/88  Added v type, sh prefix, and explanation of ha
      and 1 as prefixes applied to p for huge and far
      pointers. Also clarified use of From in pro-
      cedure names. (DBK)

04/10/90  Moved to nroff, changed references to OSAC to
      IEMIS (WKC)

Copyright info (著作権情報)


Date: Fri, 20 Sep 91 15:12:53 -0700
From: sgihbtn!billc@uunet.UU.NET (Bill Campbell)
Message-Id: <9109202212.AA04579@shared>
To: uunet!umiacs.UMD.EDU!dalamb@uunet.UU.NET
Subject: Re: Hungarian Notation References
...
I have just talked with Doug Klunder at Microsoft. He says that
publication of his paper is perfectly okay, they have not copyrighted
it. It is, of course, their preference that the document be
respresented as his/MS's work.

From: "Joel Spolsky" <spolsky@fogcreek.com>
To: <info@byteshift.de>
Sent: Thursday, May 12, 2005 12:57 AM
Subject: RE: joelonsoftware.com/articles/Wrong.html - Hungarian Notation/D. Klunder: link to clean HTML version
...
Also I have heard personally from Doug
Klunder himself that this file is in the "public domain".