1

最近の C 標準では、次のように指定されていますprintf("%s",p)

l長さ修飾子が存在しない場合、引数は文字型の配列の最初の要素へのポインタでなければなりません

pそれは と互換性がなければならないということですかchar *、それともこの文はより寛大な方法で解釈されるべきですか? 標準の他の部分は、ここで「文字型の配列」が正確に何を意味するのかを明確にしていますか?

これが重要な理由p: 句がと互換性がなければならない意味として厳密に解釈される場合char *、重要な結果は、が署名unsigned char *p; … printf("%s", p);されているコンパイル プラットフォームでは未定義であり、未定義です。charconst char *p; … printf("%s", p);

4

2 に答える 2

10

charsigned char、の 3 種類unsigned charをまとめて文字種と呼びます。...
C11 6.2.5 15

したがって、「文字タイプ」の配列には、これら 3 つが含まれます。

constvolatile、およびrestrictは、さまざまな型の修飾子であり、同じ型カテゴリに属します。それらも適用されます。

これまでに述べた型はすべて、修飾されていない型です。修飾されていない各型には、修飾子、修飾子、および修飾子の 1 つ、2 つ、または 3 つすべての組み合わせに対応する、その型の修飾されたバージョンがいくつかあります。型の修飾バージョンまたは非修飾バージョンは、同じ型カテゴリに属し、同じ表現およびアラインメント要件を持つ個別の型です。派生型は、派生元の型の修飾子 (存在する場合) によって修飾されません。 C11 6.2.5 26 constvolatilerestrict

于 2013-09-13T14:25:25.127 に答える
3

はい、p は char と互換性がある必要があります。このテキスト行の主な目的は、char と wchar_t の違いを指摘することです。同じ章 (C11 7.21/7) をさらに読むと、より明確になります。

l (エル)
「次の s 変換指定子が wchar_t 引数へのポインタに適用されることを指定します;」

を記述する場合%ls、引数は と互換性がなければなりませwchar_t[]char[]

charvs unsigned char:形式的には、 へのポインターは へのcharポインターと互換性がありませんunsigned charunsigned char*したがって、 to を渡すことprintf("%s",p)は、正式には未定義の動作です。

しかし... C標準外の現実の世界では、文字シンボルを格納する目的のunsigned char代わりに使用できない場合はありません。char単純に、負のインデックスを持つシンボル テーブルが存在しないためです。ASCII、UTF8 などはすべて 0 から始まり、そこから上に数えます。これは理論的には未定義の動作ですが、コードは 100% 移植可能です。

于 2013-09-13T14:30:46.037 に答える