命名規則は、宗教的な問題になる傾向があります。 一般的に、命名規則の1つが選択され、宗教的に守られている限り、 必要以上にそれが守られていることは重要ではありません。 Splintは2種類の命名規則をサポートしています。 型ベースの命名規則(Section 12.1)は識別子が定義された場所で アクセス可能な抽象型に応じて識別子の名前を限定します。 プレフィックス(接頭辞)の命名規則(Section 12.2)は、 何が宣言されているかと、そのスコープに応じた識別子の名前の最初の文字列 を制限します。 命名規則は組み合わされてもかまいません。もしくは、異なる規則が、 異なる種類の識別子に対して選択されてもかまいません。 また、Splintは、名前が標準ライブラリ、あるいは、実装(Section 12.3)用に予約された名前と 衝突しないことと、他の名前と十分に区別できることをチェックすることが出来ます。
一般的な命名規則は、有効な識別子の名前を制限します。 有効な名前を制限することにより、名前空間が保護されるように出来、 また、名前が、どこでどのように名前が定義され、どのように使用されるべきか? の手がかりを与えるため、プログラムがより簡単に理解しやすくすることが出来ます。
名前は、名前のスコープ(external、 file static、 internal)、 識別子を定義しているファイル、識別子の型と、グローバルの制約によって、 制約することが出来ます。
チェコ*17語名は、<type>_ による先行する名前によって操作と抽象型の変数を示します。 名前の残りの部分は小文字で始めなければなりませんが、 しかし、アンダースコア以外の文字を使用することが出来ます。 型はアンダーラインではない文字を使用して名前付けることが出来ます。
チェコの命名規則はczechフラグによって 選択されます。 access-czechフラグがオンの場合、 <type>_<name>と名付けられた 関数、変数、定数あるいはイテレータは、 抽象型<type> へのアクセス権を持っています。 チェコの命名規則の違反の報告は 宣言されているものに応じた異なるフラグによって制御されます。
czech-fcns
czech-vars
czech-constants
czech-macros
czech-types
もちろん、これは初心者への完全な寄せ集めであり、それは冗談だ。
Charles Simonyi, on the Hungarian naming convention
スロバキア語名はつづりが異なる点を除き、チェコ語名と似ています。 スロバキア語名は形式<type><Name>のものです。 型プレフィックス(接頭辞)に大文字は使用できません。 名前の残りの部分は最初は大文字で始まります。
slovakフラグはスロバキアの 命名規則を選択します。 チェコの名前のように、抽象的な表現へのアクセスを制御するために access-slovakフラグ と共に使用できます。slovak-fcnsフラグ、 slovak-varsフラグ、 slovak-constantsフラグ、と、 slovak-macrosフラグ はチェコの同様のフラグに似ています。 slovak-typeフラグがオンの場合、 型名に大文字が含まれている場合は、エラーが報告されます。
チェコスロバキア語名はチェコ語名とスロバキア語名の組み合わせです。 操作名は、<type>_の後に、 アンダースコア以外の任意の文字が続くか、あるいは、 <type>の後に、 大文字と任意の文字が続きます。 チェコスロバキア語名は1993年以降嫌われてきましたが、 レガーシーコードをチェックするためには必要かもしれません。 czechoslovak-fcnsフラグ、 czechoslovak-varsフラグ、 czechoslovak-macrosフラグ、と、 czechoslovak-constantsフラグは チェコの同様のフラグに似ています。 czechoslovak-typeフラグがオンの場合、 型名が大文字あるいはアンダースコアを含む場合はエラーが報告されます。
名前を制限するもうひとつの方法は識別子の様々な種類の主要な文字シーケンスを 制限することです。例えば、全てのユーザ定義型は、 Tで始まり、その後に、大文字が 続く、全てのファイル静的変数の名前は大文字から始まるなどです。 これは、名前空間を適用する(例えば、X-Windowライブラリによってエクスポートされた 全ての名前がXで始まる)のに便利です。 又は、単に強制された規則を確立することによってプログラムを理解しやすくする のに便利です。 Splintは、プレフィックス(接頭辞)と矛盾する識別子を検知するため、 このように識別子を制約するために使用できます。
全ての名前空間のフラグは 形式、-<context>prefix <string>のものです。 例えば、m_が先行する マクロ本体内で宣言された識別子を制限するマクロ変数の名前空間は -macrovarprefix "m_" によって選択されます。 stringにはC言語の識別子に現れる通常の文字を含んでかまいません。 これらは識別子の名前の最初の文字と一致している必要があります。 また、特殊文字(図23に示されている)が文字クラスを表すために 使用できます。 *18 *文字は、 識別子の残りが * の直前の文字に0回以上マッチすることを指定するために接頭文字列の 最後に使用してもかまいません。 例えば、接頭文字列T&*は、 T、又は、 TWINDOWではなく、 Twinに マッチします。
異なるプレフィックス(接頭辞)は以下の識別子のコンテキストを選択します。
macro-var-prefix |
マクロの本体内部で宣言された任意の変数 |
unchecked-macro-prefix |
関数あるいは定数としてチェックされない任意のマクロ (Section 11.4参照) |
tag-prefix |
struct、 union、と、 enum 宣言に対してのタグ |
enum-prefix |
enum型の メンバー |
type-prefix |
ユーザ定義型の名前 |
file-static-prefix |
ファイル静的スコープを持つ任意の識別子 |
glob-var-prefix |
グローバルスコープを持つ任意の変数 (関数型のではない) |
const-prefix |
任意の定数(Section 11.1参照) |
iter-prefix |
任意のイテレータ(Section 11.4参照) |
proto-param-prefix |
関数のプロトタイプ宣言内の変数 |
external-prefix |
任意の外部公開識別子 |
識別子が複数の名前空間のコンテキスト内にある場合、 最も具体的に定義された名前空間プレフィックス(接頭辞)が使用されます。 (例えば、グローバル変数が外部公開識別子でもある場合、 global-var-prefixが設定されていれば、 変数名とチェックされ、そうでなければ、識別子が external-prefix とチェックされます。 )
各プレフィックス(接頭辞)フラグに対して、 <prefixname> excludeと名付けられた 対応するフラグは、 異なる名前空間にある識別子が名前空間プレフィックスにマッチするときに エラーを報告するかを制御します。 例えば、macro-var-prefix-excludeフラグがオンの場合、 Splintは、マクロの本体内で宣言されている変数ではない 識別子が マクロ変数プレフィックスを使用していないことをチェックします。
これは、(やや難しい)命名規則のサンプルです。
-unchecked-macro-prefix "~*" |
定数や関数のマクロではないマクロは 小文字を含まない。 |
-type-prefix "T^&*" |
全ての型名はTで始まり、 大文字が1文字続く。名前の残り部分は全て小文字。 |
+type-prefix-exclude |
ユーザ定義型の名前で名付けられていない識別子は 型名プレフィックスで始まらない |
-file-static-prefix "^&&&" |
ファイル静的スコープの変数は大文字1文字と小文字3文字から始まります。 |
-proto-param-prefix "p_" |
プロトタイプ内の全ての引数はp_で始まらなければならない |
-glob-var-prefix "G" |
全てのグローバル変数はGで始まる。 |
+glob-var-prefix-exclude |
グローバル変数ではない識別子は Gからは始まらない |
関数プロトタイプ内の引数に対してのプレフィックス(接頭辞)は 引数名が関数プロトタイプの前に定義されたマクロと競合しないことを 確実にするために便利です。 多くの場合、プロトタイプ引数には名前をつけない方が好ましいです。 proto-param-nameフラグが設定されている場合、 プロトタイプ宣言内の名前付けされた全ての引数に対し、エラーが報告されます。 proto-param-prefixが設定されている場合、 名前付けされていない引数に対してはエラーは報告されません。
定義内の名前に対応したプロトタイプの引数の名前をチェックするのにも 便利な場合があります。 ドキュメントとしてヘッダファイルを使用することが一般に推薦されない間は、 引数名が一致していることをチェックすることは意味があることが、 一般的に十分な習慣です。 不一致は関数プロトタイプ内での引数順でのエラーを示すかもしれません。 proto-param-matchフラグが設定されている場合、 Splintは、(protoparamprefixを取り除いた後) 定義での引数の名前が対応するプロトタイプ宣言での引数とマッチしていない 場合にエラーを報告します。
^ |
任意の大文字。 A-Z |
& |
任意の小文字。 a-z |
% |
大文字ではない任意の文字 (小文字と数字とアンダースコアが許される) |
~ |
小文字ではない任意の文字 (大文字と数字とアンダースコアが許される) |
$ |
任意の文字 (a-z, A-Z) |
/ |
任意の文字あるいは数値 (A-Z, a-z, 0-9) |
? |
C言語の識別子で有効な任意の文字 |
# |
任意の数字。 0-9 |
図 23 プレフィックス(接頭辞)文字コード |
追加の名前の制限は 標準ライブラリで予約されている名前と衝突しないことと、 (コンパイラとリンカ、プログラマのどちらのためにも)その識別子が十分に異なっていることをチェックするのに 使用可能です。 制限はリンカ(external名)によって必要とされる名前と、 コンパイル単位内でのみ必要な名前(internal名) とで異なる可能性があります。 非static関数の名前とグローバル変数は externalであり、それ以外の全ての名前はinternalです。
意味上旧来の6文字の大文字と小文字を区別しない制約を保持しようとする決断は最も苦痛だった。
ANSI C Rationale
多くの名前が実装と標準ライブラリに対して 予約されています。 予約された名前の完全な一覧は[vdL, p. 126-128]にて見ることが出来ます。 strの様な小文字が続くいくつかの名前の プレフィックス(接頭辞)は、将来のライブラリの拡張のために予約されています。 ほとんどのC言語は名前の衝突を検知せず、予測できないプログラムの動作の 原因となります。 ansi-reservedフラグが オンの場合、Splintは予約された名前で衝突するexternal名について警告します。 ansi-reserved-internalフラグがオンの場合、 internal名に対しても警告が行われます。
+cpp-namesフラグがオンの場合、 SplintはC++でのキーワードや予約されている単語である識別子名について 警告します。 コードが後でC++コンパイラでコンパイラされる可能性がある場合、 これは便利です(もちろん、C++としてコンパイルされるときに コードの意味が変わらないことを確認するには十分ではありません)。
Splintは、名前が指定した文字数内で、 必要に応じてアルファベットの大文字と小文字を無視して、 似ている文字の違いで異なっていることをチェックできます。 有効文字数は、external名とinternal名とで異なる場合があります。
+distinct-external-namesフラグ を使用すると、6文字までのexternal名に対して有効文字数を設定し、 external名に対してアルファベットの大文字小文字を無意味にします。 これは、ANSI準拠のコンパイラでの最小な有効許容です。 最も近代的なコンパイラはこれらの最小値( 1つがCzechあるいはSlovak命名規則を使用したとき 従うことが特に難しい )を超えます。 有効文字数はexternal-name-length <number>フラグで変更できます。 external-name-case-insensitiveフラグが オンの場合、external名を比較する際にアルファベットの大文字小文字を無視します。 Splintはアルファベットの大文字と小文字のみが異なる識別子を報告します。
internal識別子に対して、準拠コンパイラは少なくとも31文字までを認識し、 アルファベットの大文字・小文字を区別して扱わなくてはなりません。 それでも、internal名がより区別でき、そのうえ、 識別子がプログラムの中で混乱する可能性を 最小限にするためにコンパイラによって必要とされることをチェックするのに 有用です。 external名と同様、internal-name-length <number>フラグは internal名の有効文字数を設定し、internal-name-case-insensitiveフラグは 大文字と小文字の区別を設定します。 internal-name-look-alikeフラグ は識別子間の区別を制限します。 設定した場合、似ている文字がマッチします -- 小文字のlは 大文字のIと 数字の1にマッチします; 文字Oと oは、数字の 0にマッチします; 5 はSとマッチします; そして、2は Zとマッチします。 似ている文字を除いて区別することが出来ない識別子に対して、エラーメッセージ が表示されます。 external名はinternal名でもあるため、それらは、 externalとinternalの両方で識別子の明白さチェックを満たす必要があります。 図24は、名前の明白さチェックのいくつかの例を示しています。
names.c |
Running Splint |
char *stringrev (char *s);
3 int f (int x) { 5 int lookalike = 1; 6 int looka1ike = 2;
if (x > 3) { 10 int x = lookalike; x += looka1ike; }
return x; } |
> splint names.c +distinctinternalnames +internalnamelookalike +isoreserved
names.c:1: Name stringreverse is reserved for future library extensions. Functions that begin with "str" and a lowercase letter may be added to <stdlib.h> or <string.h>. (ISO99:7.26.9) names.c:6: Internal identifier looka1ike is not distinguishable from lookalike except by lookalike characters names.c:5: Declaration of lookalike names.c:10: Variable x shadows outer declaration names.c:3: Previous declaration of x: int |
図 24. 明白な名前 |
このドキュメントはSplint(英)のサイトを元に作成しました
[PageInfo]
LastUpdate: 2014-02-11 15:06:59, ModifiedBy: daruma_kyo
[License]
Creative Commons 2.1 Attribution-ShareAlike
[Permissions]
view:all, edit:login users, delete/config:members