web-dev-qa-db-ja.com

%p形式指定子は、printfのchar *以外のすべてのタイプでvoid *に明示的にキャストする必要があります

ここStackOverflowでC言語での%p形式指定子の使用法について多くの回答を読みましたが、すべてのタイプでvoid*への明示的なキャストが必要な理由については説明がないようです。 char*
もちろん、void*との間でキャストするこの要件は、可変個引数関数の使用と関連しているという事実を認識しています(この最初のコメントを参照 answer )それ以外の場合は必須ではありません。

次に例を示します。

int i;    
printf ("%p", &i);

タイプの非互換性に関する警告が表示され、&ivoid*にキャストされます(標準で要求されているように、もう一度参照してください ここ )。

このコードのチャンクは、型キャストについて何の不満もなくスムーズにコンパイルされます。

char * m = "Hello";    
printf ("%p", m);

char*がこの命令から「解放」されるのはどうしてですか?

[〜#〜] ps [〜#〜]:私が取り組んでいることを追加する価値があるかもしれませんx86_64アーキテクチャ、ポインタ型のサイズはそれに依存するため、Linuxのコンパイラとしてgccを使用し、-W -Wall -std=c11 -pedanticコンパイルオプションを使用します。

17
programmersn

char*にはchar *と同じ表現と配置要件があるため、タイプvoid *の引数に明示的なキャストは必要ありません。

C11の引用、§6.2.5章

Voidへのポインタは、文字タイプへのポインタと同じ表現および配置要件を持つ必要があります。 (48) [...]

および脚注48)

同じ表現と配置の要件は、関数への引数、関数からの戻り値、および共用体のメンバーとしての互換性を意味することを意味します。

20
Sourav Ghosh

C11標準6.2.5/28は次のように述べています。

Voidへのポインタは、文字タイプへのポインタと同じ表現および配置要件を持つ必要があります。 48)

脚注48は次のとおりです。

同じ表現と配置の要件は、関数への引数としての互換性、関数からの戻り値、および共用体のメンバーを意味することを意味します。

ただし、7.21.6.1( "fprintf関数")は_%p_について次のように述べています。

引数はvoidへのポインタでなければなりません。


これは明らかに矛盾です。私の意見では、6.2.5/28の意図は、_void *_と_char *_は、プロトタイプに対応しない関数の引数の型として実際に交換可能であるということです。 (つまり、プロトタイプ化されていない関数への引数、または可変個引数関数のプロトタイプの省略記号との一致)。

どうやらあなたが使用しているコンパイラは同様の見方をしています。

これを裏付けるために、7.21.6.1の引数タイプの仕様は、意図に関係なく文字通りに解釈された場合、実際には無視しなければならない他の多くの矛盾があります(たとえば、printf("%lx", -1);は適切であると言われています-定義されていますが、printf("%u", 1);は未定義の動作です)。

9
M.M

この要件の理由は、C標準では、2つの注目すべき制約があり、さまざまなタイプへのポインターのさまざまな表現が許可されているためです。

したがって、一部のアーキテクチャでは、_int *_と_char *_の表現が異なる場合があります。たとえば、サイズが異なり、さまざまな方法でvararg関数に渡され、int i = 1; printf("%p", &i);int i = 1; printf("%p", (void*)&i);の動作が異なります。

ただし、Posix標準では、すべてのポインタータイプが同じサイズと表現であることが義務付けられていることに注意してください。したがって、Posixシステムでは、printf("%p", &i);は期待どおりに動作するはずです。

C Standard#6.2.5p28から

voidへのポインタは、文字へのポインタと同じ表現および配置要件を持つ必要があります type.48)同様に、互換性のある型の修飾バージョンまたは非修飾バージョンへのポインタは、同じ表現および配置要件を持つ必要があります。構造タイプへのすべてのポインタは、互いに同じ表現と配置の要件を持つ必要があります。共用体タイプへのすべてのポインターは、互いに同じ表現および配置要件を持つ必要があります。他のタイプへのポインタは、同じ表現または配置要件を持つ必要はありません。 [強調鉱山]

3
H.S.