2017年4月13日木曜日

%p 使ってますか?



こんにちは。よっしーです。

今日は『C言語』についてお話ししたいと思います。

C言語にはポインタというものがあります。

メモリ上のアドレスを指し示すものですが、
このアドレスの値が知りたい場合、以下のような
コードを組むケースがあります。

char* p = (char*)malloc(BUF_SIZE);
printf("p=%x\n", p);

ポインタ値を出力するため、
フォーマット指定子に "%x" を使用するという
よくあるコードですが、

実はこれ、あまりよくないコードです。


というのも、最近、
ILP32で組まれているコードをLP64に対応(64bit化)する。
というお仕事があり、

試しに64bit環境で、既存のILP32コードをビルドすると、
上記のようなコードは、以下のようなワーニングが出力されます。

warning: format ‘%x’ expects type ‘unsigned int’, but argument 2 has type ‘char *’


そもそも "%x" は、unsigned int を 16進数表示 する。という指定子なので、
ポインタを対象に使用することが間違いです。

LP64ではポインタが64bitの幅を持つこととなるため、
これに "%x" を指定すると、unsigned int(32ビット)に暗黙変換されてしまい、
上位ビットがオーバーフローします。


ポインタの値を出力する場合、ポインタ用のフォーマット指定子 "%p" を使用する。
というのが、正しいコードとなりますので、みなさんも気をつけましょう。

printf("p=%p\n", p);

それでは、また。


0 件のコメント:

コメントを投稿