2010-05-27

cstdint.hのMIN/MAXマクロ

どうも、皆たったのC99規格の2パラグラフが読めないようなので、翻訳する。

7.18.2 Limits of specified-width integer typesより、パラグラフ1

The following object-like macros specify the minimum and maximum limits of the types declared in <stdint.h>.

以下のオブジェクトに似せたマクロは、<stdint.h>で定義されている型の、最小と最大の制限を指定するものである。(略)

これだけ読むと、実際の最小値と最大値のように読める。次に、パラグラフ2だ。

Each instance of any defined macro shall be replaced by a constant expression suitable for use in #if preprocessing directives, and this expression shall have the same type as would an expression that is an object of the corresponding type converted according to the integer promotions.

すべてのマクロは、#ifプリプロセッサディレクティブで使える定数式に置換されなければならず、その式は、integer promotionによって、対応する型と同じ型に型変換できなければならない。

これにより、キャストはできない。integer promotionによって型変換された結果、その型と同じになればいいので、正直なところ、渡された値を、そのまま使うしかない。これは、(2) - 危ないRiSKのブログへの反証にもなる。ただし、整数リテラルのサフィックスを付け加えて、符号を整えるぐらいはするべきだろう。そういう意味で、MSVCの実装は、すこし劣っている。とはいえ、Cのinteger promotionで同じ型に型変換できればいいのである。Cの型システムに頼っているのであるから、サフィックスを使わなくても、規格準拠であろう。ましてや、integer promotionだ。続き。

Its implementation-defined value shall be equal to or greater in magnitude (absolute value) than the corresponding value given below, with the same sign, except where stated to be exactly the given value.

その実装定義の値は、以下に定義された値に対して、等しいか、より大きくなければならない。符号は同じである。ただし、厳密に規定された値と記されている場合を除く。

厳密に指定されているのは、INTN_MIN、INTN_MAX、UINTN_MAXだけである。つまり、この三つのマクロは、規格の定義する値と、同じでなければならない。たとえ、uint8_tが、内部的に16bitであり、その最大値は、216 − 1だったとしても、UINT8_MAXの値は、28 − 1になる。

さて、それ以外の場合。

「等しいか、より大きくなければならない」なので、等しい場合も、規格準拠の実装である。たとえば、UINT_LEAST8_MAXが、実際は16ビットの整数であり、その実際の最大値は、216 − 1だったとする。しかし、28 − 1に等しいか、それより大きければ(ただし、単位は桁である。2の累乗のことだ)、規格上は問題ない。

これらのマクロは、最低限保証されている最小値と最大値を取得するものである。実装における本当の最小値と最大値を取得するものではない。それでは役に立たぬではないかという意見もあるだろう。しかし、規格準拠の実装は、役に立つかどうかで判断されるものではない。規格に照らし合わせて、準拠しているかどうかで判断しなければならない。もし、それが役に立たぬとすれば、それは規格の問題である。

個人的に言えば、これはプリプロセッサを使うから、こうなってしまうのである。プリプロセッサは根本的に邪悪で低機能であり、こうなるのも仕方がない。クラスとテンプレートさえあれば、C++の、std::numeric_limitsのようなテクニックで実装できる。これはもちろん、#ifでは使えない。しかし、C++ならば、最小値最大値に関わる実装分岐程度の問題は、プリプロセッサではなく、テンプレートメタプログラミングで解決できる。

基本的に、これらの技術文章は、日本語に翻訳すると、非常に分かりにくくなる。原文が英語である以上、当然英語で理解すべきである。

3 comments:

Anonymous said...

>> ... the minimum and maximum limits of the types ...
> これだけ読むと、実際の最小値と最大値のように読める
素直に読めば「型の最大最小」ですが、なぜこれを「実際の」などと "of the types" を無視した解釈にする必要があるのでしょう?

> たとえ、uint8_tが、内部的に16bitであり(略)だったとしても
uint8_t は必ず 8bit ぴったりの整数でなければなりませんので、この仮定はナンセンスです。

江添亮 said...

>uint8_t は必ず 8bit ぴったりの整数
そういえばそうだった。leastのつもりで書いていました。

江添亮 said...

「実際の」というのは、たとえばuint_least8_tの、内部的な型(8ビットとは限らない)の最大最小という意味で使ったのですが。