を渡しますにより、printf

gccの日本語メッセージ。

hogehoge.c: 関数 `func' 内:
hogehoge.c:15: 警告: 引数 1 個の `arg' を渡しますにより、キャストなしでポインタから整数を作りました

funcという関数の呼び出しを書くときに1個目の引数の型が違ったので明示的にキャストされていないけど勝手にキャストしてポインタを整数にして渡しちゃったけど、渡された先で何が起ころうと知ったことじゃありません、という警告だ。

不自然とかそういう問題じゃないように思う。ずいぶん前からこうなってるんだけど、指摘しなきゃ誰も気づかないのかな。もしかしたら、おもしろいからそのままにしているだけかもしれないね。あるいは、makeの「入りますディレクトリ」が見えてるから、gcc側がおかしくても気にならないのかもしれない。

で、やはり疑問なのでgccのソースの中にあるja.poを見たら、確かにそうなるのもうなずけるなーと思った。というのは、passing arg %d of `%s’引数%d個の`%s’を渡しますと訳すのは間違いじゃない(実際の意味は個数じゃないけど)。そして%s makes integer from pointer without a cast%sにより、キャストなしでポインタから整数を作りましたと訳すのも間違いじゃない。でもつながらない。

別に「〜により」にこだわることはなくて、passing arg %d of `%s’は「`%2$s’への%1$d番目の引数が原因です。」にして%s makes integer from pointer without a castは順序を変えて「キャストなしでポインタから整数を作りました。%s」とかにするのが自然かな。つなげると「キャストなしでポインタから整数を作りました。`func’への1番目の引数が原因です。」になる。でも順序を変えたりすると文句を言われそうだし、printfの「%n$」なんて知らない人も多いからメンテナンス性が悪くなってしまう。今はソース上は文字列はすぐにprintf()に渡るからいいけど、そうならなくなったら「%n$」は使えなくなる。それに別の文脈で同じ文字列が使われて、そっちではpassing arg %d of `%s’は「原因」じゃなかったりするかもしれない。

あとprintfを提供するライブラリ側で「%n$」に対応してなかったらどうするんだって話もある。簡易のlibcを使っている場合や、滅多に使わない機能なのでテストされてなかったりする環境も充分にありうる。

ちなみに、引数を1個スキップするだけなら「%*s」みたいに書ける。つまり、printf("%*s\n", 1, "test");だと「test\n」が出力される。

printfは奥深い。printf(3)のman pageだけ読んで使い方を理解できる人は少数派だろうな。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です