2009-03-31 9 views
5

printfのマニュアルページを見ていて、何かが私に起こりました。私は、比較的簡単な質問に答えることができる "言語弁護士"がいるかどうか疑問に思っていました。互換性のないprintf書式指定子に関する質問

Soは 'T' 修飾子は

がptrdiff_tの引数に対応する整数変換として定義されます。

だから、これを符号なし整数変換と組み合わせるととなると思いますか?明らかに、o、u、x、およびXはすべて符号なしの値として解釈され、dとiは符号付きです。

同様に、ptrdiff_tを除くすべての修飾子(int/unsigned int、size_t/ssize_tなど)には符号付き/符号なしのバージョンがあります。

実際には、署名されていないバージョンのタイプは署名されたバージョンと同じ量のスペースを占めるため、何も悪いことはありません。だから、バイトの権利はスタックからポップされます。

だから、何も "悪い" のプリントで、実際には、 "INT_MIN" を除いて、試験した全てのものの期待値を起こりません(と仮定sizeof(int) == sizeof(ptrdiff_t)いる。

printf("%tu %td\n", INT_MIN, INT_MIN); 

プリント上

2147483648 -2147483648 

32ビットシステム

標準についてはこれについて意見がありますか?私は答えが "未定義の動作"になると考えています。

+0

と協力しなければならない

  • これは持っていますC++(少なくともC++ 0xの前)とは何か? printf()などはC++ 0xで変更され、C99に準拠しますか?私はあなたがC + +タグを削除する必要がありますと思う。 –

  • +0

    ptrdiff_tはC++のcstddefで定義されています。 printfは明らかにC++にも存在します。私はprintfを変更してもC++ 0xを意識していません。 –

    +0

    hrmm、C++にc99 't'修飾子がないようです。けっこうだ。 –

    答えて

    3

    ここをクリックしてください。あなたが書いたコードは合法です。

    ただ、理由としていくつかの事実:

    • すべての符号付き整数型は、同じサイズ/位置合わせ要件に
    • ptrdiff_tが標準で符号付き整数型であることを規定している、符号なしの対応を持っています。したがって、署名されていない双子があります。 (実際には、同様のロジックが同様size_tに適用される - ssize_tはCではありませんが、POSIX)t長指定子はdiouxX種類
    +0

    ptrdiff_tと有効な符号なしの同等物は何ですか? – user83255

    +0

    特別な名前はありません - ptrdiff_tが "long long"で、その符号なしカウンターパートが "unsigned long long"などとしか言えません – jpalecek

    +0

    あなたが省略した重要な事実は、値が整数型の符号付きおよび符号なしバリアントに適合する場合は、同じ表現を持ち、標準では、この場合「間違った」引数型を明示的に渡すことができることです。とにかくプロトタイプと可変機能を持たない関数に対してのみ可能です)。私が知る限り、UBは、フォ​​ーマット指定子が符号なしタイプを期待するとき、負の 'ptrdiff_t'値を渡すでしょう。 –