新しい (ビット幅固有の) printf() 形式オプション文字列が C99 の一部として採用されなかったのはなぜですか?
-
19-09-2019 - |
質問
クロスプラットフォームのやり方を研究中 printf()
C で文字列をフォーマットします (つまり、各整数引数が期待するビット数を考慮に入れます) printf()
はずです)私は出くわしました ウィキペディア記事のこのセクション printf()
. 。この記事では、に渡すことができる非標準オプションについて説明します。 printf()
次のような形式文字列 (Microsoft 固有の拡張子と思われる):
printf("%I32d\n", my32bitInt);
さらに次のように述べています。
ISO C99には、プラットフォームに依存しないPrintFコーディングで使用するための多数のマクロを含むIntTypes.hヘッダーファイルが含まれています。
...次に、ヘッダー内にあるマクロのセットをリストします。ヘッダー ファイルを見ると、それらを使用するには次のように記述する必要があります。
printf("%"PRId32"\n", my32bitInt);
私の質問は次のとおりです。私は何かを見逃していますか?これは本当に C99 の標準的な方法なのでしょうか?もしそうなら、なぜですか?(とはいえ、このようにフォーマット文字列を使用するコードを見たことがなかったとしても、それは非常に面倒に思えるので、驚くことではありません...)
解決
C理由は、
の
のいくつかの既存の64ビットシステムで見つかった同じ名前のヘッダに由来した。
が、テキストの残りの部分は、これらのマクロについて記述していない、と私は彼らが一度に練習を既存た覚えていません。
以下は単なる憶測ですが、標準化委員会がどのように動作するかの経験によって教育を受けています。
(C99はまた、いくつかを追加しましたことに注意)のprintfのための追加の書式指定子を標準化にわたるC99マクロの利点の一つは、あなたがすでに実装、実装に必要な機能をサポートする特定の方法は2つだけを書いている持っているとき<inttypes.h>
と<stdint.h>
を提供することです十分なのtypedefやマクロを含むファイル。これは、既存の実装の準拠を作るのコストを削減し、既存の実装仕様の機能を利用した既存のプログラムを壊すのリスクを低減(標準的な方法が干渉しない)と実装に準拠したプログラムの移植を容易にこれらを持っていない人ヘッダ(彼らはプログラムによって提供することができます)。実装の具体的な方法は、すでに一度に変化させた場合また、それは別の上に1つの実装をfavorizeません。
他のヒント
正しい、これはC99標準では、あなたがそれらを使用する必要があると言う方法です。あなたは手紙〜100%の標準に準拠している、本当にportabltコードをしたい場合、あなたは常にint
と"%d"
使用int32_t
を使用して"%"PRId32
を印刷する必要があります。
ほとんどの人は、しかし、気にしないだろう。あなたがのWin16やDOSにあなたのコードを移植している場合を除き、それは偶然にsizeof(int32_t) <= sizeof(int)
としてint32_t
をprintfのために無害ですので、あなたは、そのint
をとることができます。同様に、long long
はかなり普遍的に64ビット(そうであることが保証されていないが)であるので(例えばint64_t
指定子を有する)long long
として%llx
を印刷することも安全である。
のタイプがら、int_fast32_t
をint_least32_t
めったに使用されていないので、あなたはそれに対応するフォーマット指定をさらにほとんど使用されていないことを想像することができます。
あなたは常に上向きにキャストし、%jd
の書式指定子であるintmax_t
を使用することができます。
printf("%jd\n", (intmax_t)(-2));
<時間>
私はその後intmax_t
を使用し、任意のintXX_t
を使用することができることを示すためにlong
を使用し、単にint32_t
にキャストすると、%ld
ケースのためにはるかに優れています。
その理由については推測することしかできません。上記の AProgrammer の回答は気に入っていますが、見落とされている側面が 1 つあります。 printf にフォーマット修飾子として何を追加しますか? printf 形式の文字列で数値を使用する 2 つの異なる方法 (幅と精度) がすでに存在します。引数の精度が何ビットであるかを示すために 3 番目の種類の数値を追加するのは素晴らしいことですが、人々を混乱させずにどこに置くのでしょうか?残念ながら、C の欠陥の 1 つは、printf が拡張できるように設計されていないことです。
マクロはひどいものですが、32 ビットと 64 ビットのプラットフォーム間で移植可能なコードを作成する必要がある場合、マクロは天の恵みです。間違いなくベーコンを救いました。
あなたの質問に対する答えは なぜ どちらかです
- これより良い方法を誰も思いつきませんでした。あるいは、
- 標準委員会は、明らかに優れていると思われる点については同意できませんでした。
別の可能性:下位互換性。さらに形式指定子を追加すると、 printf
, 、または追加のオプションを使用すると、C99 以前のコードの指定子で書式指定文字列が異なる方法で解釈される可能性があります。
C99 の変更では、の機能は変更されません。 printf
.