命名規則¶
これらの規則は、すべての新しいコードに適用されるべきであり、既存のコードを修正する際には、常識的に判断して適用する必要があります。たとえば、広く使用されている既存の関数をこれらの規則に従って名前を変更することは、コード全体を大幅に修正する場合を除き、正当化されない可能性があります。
現在、このドキュメントはコードの現在の状態のみを記述しており、命名の一貫性を確保するための試みは行われていません。
ファイル¶
C++のソースファイルは拡張子を``.cpp``、Cのソースファイルは``.c``、そして両方のヘッダーファイルは``.h``を使用します。
ソースファイル:
{file}.c、{file}.cppの場合、ソースファイル外で利用可能な宣言は、対応する名前のヘッダーファイル:{file}.hに記述する必要があります。ただし、APIの可読性や使いやすさを向上させるために、このルールから逸脱するコードも存在します。その場合、明確にドキュメント化する必要があります。また、
:file:`{file}_impl.h`というファイルが存在し、モジュール外からはアクセスできないクラスや関数を宣言することも可能です。もしファイル全体がモジュール内のシンボルのみを宣言している場合、:file:`_impl.h`という接尾辞は省略されます。ほとんどの場合、単一のソースファイル外で使用されない宣言は、そのソースファイル内に存在します。
使用サフィックス:
-doc.hを、特定のモジュールのみに Doxygen ドキュメントが含まれるファイルの場合、または自然な単一のヘッダーファイルを作成できない場合に、使用してください。C++ファイルの場合、ファイル名を(メイン)クラスと同じ名前にすることをお勧めします。 現在、ファイル名はすべて小文字ですが、クラス名は大文字を使用しています。 一般的に使用される略語を使用したり、不要な繰り返しを避けるために、包含するディレクトリの名前を省略したりすることも可能です(たとえば、ディレクトリ内のすべてのファイル名の一般的なプレフィックスとして使用する場合)。 その場合、残りのファイル名が十分にユニークである必要があります。
同じ名前のファイルを異なる場所で複数作成することは避けてください。これにより、ファイルの検索が困難になるだけでなく、同じ名前のC++ソースファイルは、一部のコンパイラで予期せぬ問題を発生させる可能性があります。現在、ユニットテストは例外であり(この問題が発生したのは特定のコンパイラのみで、問題が複数のテストファイルに影響を及ぼす場合に、回避策を講じることができます)。
一般的なCおよびC++コードのガイドライン¶
プレプロセッサのマクロはすべて大文字で記述する必要があります。先頭にアンダースコアを使用しないでください。C/C++の標準では、すべてのアンダースコアを含む名前は予約されています。
名前には、例えば
GMX_DIRNAME_HEADERNAME_Hのようなプレフィックスを含めることができます。一般的な読者には自明でない略語の使用は避けてください。
もし名前で使用する略語(例:PME、DD)については、Microsoftの命名規則に従ってください。2文字の場合は大文字(DD)、3文字以上の場合は小文字(Pme)を使用します。もし、その略語が使用されているコンテキスト(例:関数の名前の先頭、またはC関数の名前のどこか)で通常小文字で表記される場合(例:Pme)、すべて小文字の略語を使用するのが最も明確です。
Cコード¶
すべての関数と変数の名前は小文字で、必要に応じてアンダースコアを使用して区切り文字として使用します。
すべての、公開APIの一部である関数は、「gmx_」で始まるようにしてください。 理想的には、他の関数も同様に「gmx_」で始めるのが良いでしょう。 一部のコードでは、内部関数に対して「_gmx_」というプレフィックスが使用されていますが、厳密にはこれらは予約された名前なので、例えば、末尾にアンダースコアを使用する方が適切です。
古いCコードや、それに対する変更は、ブール値や列挙変数の名前、および列挙値に対して、それぞれ「b」または「e」をプレフィックスとして使用したハンガリー記法を使用し続けることができます。あるいは、以下に示すC++の慣習に徐々に移行することも可能です。どちらを選択する場合でも、複雑な略語の使用は避けてください。
C++コード¶
すべての名前にはキャメルケースを使用してください。 型(クラス、構造体、typedef、および列挙値など)はすべて大文字で始め、その他の名前(関数、変数)はすべて小文字で始めてください。 クラスが外部の構造(たとえば、標準ライブラリの構造)と名前が一致する場合、小文字とアンダースコアを組み合わせて使用することもできます。
C++ のインターフェースには、「I」という接頭辞を使用します(例:ICommandLineModule)。これにより、インターフェースが識別しやすくなり、不要な冗長性を増やすことなく(インターフェースは通常、非常に広範囲で使用されるため、「Interface」という単語を記述すると、多くの名前が不必要に長くなるため)。
抽象基底クラスは通常、「Abstract」というプレフィックスが付いた名前で命名されます。
メンバー変数は、末尾にアンダースコアが付いた名前で命名されます。
変数「foo_」へのアクセス用メソッドは、「foo()」と「setFoo()」という名前で定義されています。
グローバル変数は
g_というプレフィックスで命名されます。グローバルおよびファイル固有の変数は、「g_」というプレフィックスで命名されます。
静的クラスと関数の変数は、「s_」というプレフィックスで命名されます。
静的な
constexprファイル、クラス、または関数のメンバは、「sc_」というプレフィックスで命名されます。グローバル定数は通常、「c_」というプレフィックスで命名されます。
もしファイルが特定のクラスを実装することに主に焦点を当てている場合、ファイル名は、ファイル名の繰り返しを避けるために可能な限りそのクラスと一致させる必要があります(たとえば、モジュール内のすべてのクラスがモジュール名で始まる場合、モジュール名を省略または短縮しても構いません)。 現在、すべてのソースファイル名は小文字ですが、この大文字・小文字の違いが唯一の違いであるべきです。
新しいC++コードでは、C言語に由来するハンガリー記法(つまり、ブール変数には「b」プレフィックス、列挙変数または値には「e」プレフィックスを使用する慣例)の使用を避けてください。代わりに、制御する内容を明確に記述した、長い名前を使用してください。ブール変数には通常、「foundAtom」のような動詞を含めます。
通常のenumよりも、クラスのenumを使用することを推奨します。これにより、予期しないintへの変換を防ぐことができます。
名前を「enumValueToString」のように、クラスの列挙値を文字列に変換する関数に設定します。
非クラス型の列挙を使用する場合は、列挙型の名前を列挙値の名前のベースとして含めることを推奨します。例えば、設定を他のモジュールで公開する場合は、特に
HelpOutputFormat_Consoleのように、列挙型の名前を含めるようにします。関数における制御パラメータとして、ブール値ではなく、列挙型と値を優先的に使用することを推奨します。これにより、「HelpOutputFormat_Console」が何を制御しているのかが理解しやすくなりますが、「TRUE」が同じ場所で使用されている場合、その役割を理解することはほぼ不可能です。
背景として、末尾のアンダースコアとグローバル/静的プレフィックスを使用する理由は、メソッド内で参照される変数が、その関数に局所的なものなのか、それともより広い範囲にまたがるものなのか、すぐに判断できるため、コードの可読性を向上させるためです。
GPU向けのコード¶
理由: GPUを使用する場合、適切なメモリ空間を使用することが、パフォーマンスにおいて非常に重要です。
CUDA デバイスコード(
sm_、gm_、cm_``プレフィックスを使用)では、共有メモリ、グローバルメモリ、および定数メモリには、``sm_、gm_、および``cm_``プレフィックスが使用されます。プレフィックスがない場合、レジスタ空間を示します。OpenCLコードでも同様のプレフィックスを使用し、``sm_``はローカルメモリを示し、プライベートアドレス空間の変数にはプレフィックスは追加されません。ホストと通信するデータは、CPUとGPUの両方のメモリ空間に存在する必要があります。したがって、ホストメモリには、CUDAの場合はポインタまたはコンテナ、OpenCLの場合はメモリバッファのような、デバイスに対応するものが存在することが一般的です。これらのオブジェクトを簡単に区別するために、これらの変数の名前は「h_」と「d_」でプレフィックスされ、それ以外は同じ名前になります。例:
h_massesとd_masses。その他の場合は、ホストメモリへのポインタは、ホストコードのどの部分であっても、``h_``というプレフィックスを持つ必要はありません(ホストとデバイスの両方のポインタが存在する部分でも)。 デバイスポインタは、常に``d_``または``gm_``というプレフィックスを持つ必要があります。
GPUカーネル引数が構造にまとめられている場合、構造内のすべてのデバイスメモリポインタに「d_」というプレフィックスを付けることが推奨されます(たとえば、「kernelArgs.d_data」は「d_kernelArgs.data」よりも好ましいですが、「d_kernelArgs.d_data」と「kernelArgs.data」の両方は使用できません)。
注意: 同じポインタは、ホストコードでは
d_、デバイスコードではgm_のプレフィックスを持つ可能性があります。たとえば、カーネルにd_dataが引数として渡される場合、カーネル引数のリストでgm_dataにエイリアスする必要があります。デバイスポインタが渡された構造体のフィールドである場合、直接使用するか、gm_プレフィックスを持つポインタにエイリアスすることができます(例:kernelArgs.d_dataはそのまま使用するか、またはカーネル内でgm_dataにエイリアスすることができます)。CUDAワープ、スレッド、ブロックのインデックスや、それに対応するOpenCLのインデックス(例:
threadIndexをiやatomIndexよりも使用する方が望ましい)について、意味のない名前を使用することは避けてください。
ユニットテスト¶
テスト用データ(
TEST/TEST_Fの最初の引数)は、「Test」という接尾辞が付いた名前で指定されます。テスト用設定(または、設定として使用される名前)として使用されるクラスは、「TestBase」または「Fixture」という接尾辞で命名されます。
CTestのテストは、CamelCaseで命名され、末尾に「Tests」が付いています(例:「OptionsUnitTests」)。
テストバイナリの名前は、モジュールの名前と
-testという接尾辞で構成されます。