2017-02-23 25 views
5

printf%pフォーマット指定子のフラグとして「0」が追加されていますか?%pのprintf書式指定子フラグ '0'は正しいかどうか?

#include <stdio.h> 
int main() 
{ 
    int a = 42; 
    void* p = &a; 
    printf("Pointer address: %08p", p); 
    return 0; 
} 

Ideoneでも。上記と同様のいくつかのコードをコンパイル

、私は何の警告を持っていないか、全くのMicrosoft Visual C++ 2015が、GCC 5.4.0からの警告から:

「警告: 『%pを』で使用され、 『0』フラグ

0:整数と浮動小数点数の変換、先行ゼロ のスペース文字の代わりにパッドにフィールドを使用しているgnu_printf形式[-Wformat」

cppreference printfから読み取り、私はそれを参照してください。整数 の場合、精度が明示的に指定されている場合は無視されます。 の場合、このフラグを使用するその他の変換では、定義されていない動作が発生します。 - flagが存在する場合は、 が無視されます。

私が解釈できる限り、%pはポインタアドレスのためのもので、結局整数です。この未定義の動作は%pに適用されますか?
GCC -Wformat警告が表示されないのはなぜですか?

+0

oook、なぜdownvote? – roalz

+0

基本的な構文上の理由でコンパイルされないコードはナンセンスなので、私は推測できますか? – Lundin

+0

Jez、右、Ideoneのコピー&ペーストが動作しないことを発見したところです。私が期待したように、編集しました。 – roalz

答えて

5

%pは、ポインタが数値表現を持っていますが、標準は、ポインタ整数データ型を考慮していないすべての

後に整数であるポインタ・アドレスのためのものです。したがって、%08p形式を使用すると、未定義の動作が発生します。

あなたはそれにあなたのポインタを変換し、using uintptr_t data typeによってこの問題を回避して、符号なし整数としてそれを印刷することができます。

#include <cinttypes> 
#include <cstdint> 

int main() { 
    int i = 123; 
    void* p = &i; 
    printf("%08" PRIxPTR "\n", (uintptr_t)p); 
    return 0; 
} 

Demo.

4

% pは

がいいえ、ポインタがビューのC/C++型システムの点から整数でない、すべての後に整数であるポインタアドレスのためのものです。

ポインタは算術型でも汎整数型でもありません。std::is_integralstd::is_arithmeticを参照してください。

関連する問題