あなたの例では、両方がint値としてprintfの可変個引数パラメータリストにプッシュされます。これにより、のフォーマット文字列のフォーマットフラグがprintf()
基になるタイプと一致しないという問題が発生する可能性があります。未定義の動作が発生する理由については、この投稿を参照してください。
恐ろしいように思えますが、これで探しているものを取得できることを知る1つの方法は、次のことをprintf
行うことです。
#include <stdio.h>
#include <stdlib.h>
#define LOWER 0
#define UPPER 300
int main()
{
printf("%d %f", (int)LOWER, (float)UPPER);
return 0;
}
どちらの場合も、これらはコンパイル前に置き換えられるプリプロセッサマクロです。UPPERをに昇格できない場合float
は、コンパイラエラーが発生することに注意してください。これは良いことです。可能であれば、そうなり、printf()
必要なものを印刷するために必要なバイトが検出されます。int
同じことがそれぞれとLOWERにも当てはまります。上記のprintfは、前処理後にこれに縮退します。
printf("%d %f", (int)0, (float)300);
ここで、マクロが代わりにそのように宣言されたと想像してください。
#define LOWER 100.0
#define UPPER 300.0
オリジナルprintf()
は、前処理後にこのように表示されます。
printf("%d %f", 100.0, 300.0);
これは正しいように見えるかもしれませんが、100.0 floatは実際に%d
フォーマット文字列ハンドラーによって適切に削除されるのprintf()
でしょうか?確実に。以前に行ったことを行う:
printf("%d %f", (int)LOWER, (float)UPPER);
現在、次のように前処理されます。
printf("%d %f", (int)100.0, (float)300.0);
floatからintへのキャストでコンパイラの警告が表示される場合がありますが、表示されない場合があります。渡すものがバイトサイズのサイコロを振る必要がない限り、printf()
すべてが一致していることを確認してください。これは、フォーマット指定子が1つのことを期待し、別の何かが渡される場合に特にイライラする可能性がありますが、それでもすべて正常に機能しているように見えますが、一部のプラットフォームでのみ不思議なことになります。
printf("%ld\n", UPPER);
これは「機能する」可能性がありますが、機能する場合は、a long int
とa int
がプラットフォーム上で同じサイズであるためです。このコードを、ビット幅とUBが完全に異なるプラットフォームに移動しますlong int
。int
結論:プリプロセッサマクロをprintf()
、プッシュされるデータのサイズが期待されるようなもの(たとえば、フォーマット文字列で指定される)の可変個引数パラメータリストに渡す場合は、プッシュするものが期待されるものであることを確認する方が適切です。