EmacsのCソースコードにおける整数型の使用に関するガイドラインを以下に示します。これらのガイドラインでは時に相反する指示がなされることがありますが、常識的な判断が求められます。
s の長さが int の範囲に収まる必要がある場合を除き、int len =
strlen (s); は避けてください。
unsigned int以上である場合、符号なしオーバーフローは2のべき乗を法として確実に循環します。
unsigned int
より狭い整数型を用いたラップアラウンド演算を確実に実装するには、<stdckdint.h> のマクロを使用してください。<stdckdint.h> は C23 まで標準化されていませんでしたが、C23
以外のプラットフォームでは、Emacs
が内部的にフォールバック用の代替手段を提供しています。フォールバック用マクロが引数を複数回評価する可能性があるため、そのマクロ ckd_add、ckd_sub、ckd_mul に複雑な引数を渡さないようにしてください。
ptrdiff_t ではなく size_t、あるいは
intptr_t ではなく uintptr_t
とするなど)。
int
を優先してください。より一般的に、画面の列数など、int の範囲にあることが分かっている整数には
int を優先してください。
ptrdiff_t を優先してください。つまり、個々の C
オブジェクトの最大サイズ、または任意の C 配列の最大要素数で制限される整数の場合です。これは、符号付き型を優先するという Emacs
の一般的な方針の一環です。ptrdiff_t を使用するとオブジェクトは PTRDIFF_MAX
バイトに制限されますが、より大きなオブジェクトはいずれにせよポインタの減算を破綻させるため問題となります。したがって、これは恣意的な制限を課すものではありません。
ssize_t 関連の制限がある低レベルAPIとの通信時を除き、ssize_t の使用は避けてください。一般的なプラットフォームでは ptrdiff_t と同等ですが、ssize_t
の方が範囲が狭い場合があるため、サイズ関連の計算に使用するとオーバーフローが発生する可能性があります。また、ptrdiff_t の方がより広く普及しており標準化も進んでおり、標準的な printf フォーマットを備えているほか、Emacs
の内部的なサイズオーバーフローチェックの基盤となっています。ssize_t
を使用する際は、POSIX では −1 .. SSIZE_MAX
の範囲の値のみがサポートされている点にご注意ください。
intptr_t
を優先して使用してください。ただし、ページ境界をまたぐ可能性のあるポインタ演算を表現する場合は、uintptr_t を優先してください。例えば、32ビットアドレス空間を持つマシンでは、配列が
0x7fffffff/0x80000000 の境界をまたぐことがあり、(intptr_t)
0x7fffffff に 1 を加算すると整数オーバーフローが発生します。
EMACS_INTに基づいているため、Emacsで定義されている型EMACS_INTを優先してください。
off_t、time_t)を優先して使用してください。安全であることが分かっている場合を除き、システム型が符号付きであると想定しないでください。例えば、off_tは常に符号付きですが、time_tは必ずしもそうであるとは限りません。
intmax_t
を優先してください。printf 系の関数であれば、"%"PRIdMAX のようなフォーマットを用いてそのような値を出力できます。
bool、false、true を優先して使用してください。bool
を使用すると、プログラムの可読性が向上し、int
を使用するよりもわずかに高速になる場合があります。int、0、1
の使用も問題ありませんが、この古いスタイルは段階的に廃止されつつあります。bool
を使用する場合は、bool
の置換実装の制限に従ってください。特に、ブール型のビットフィールドは、標準的な GCC で Objective C
をコンパイルする場合でも正しく動作するよう、bool ではなく bool_bf 型とする必要があります。
intは移植性が低いため(符号付きの場合もあればそうでない場合もある)、intよりもunsigned intまたはsigned intを優先してください。単一ビットのビットフィールドは、値が0または1となるようunsigned intまたはbool_bfとしてください。