2017-01-17 10 views

答えて

5

可能な場合、タイプは通常のプロモーションルール(さらに2つの例外)ごとにプロモートされます。宣伝ができない場合は、動作が7.16.1.1(強調鉱山)あたりのC11で定義されていない:

のva_argマクロは、指定されたタイプ と呼び出しの次の引数の値を持つ式に展開されます。パラメータapは、 がva_startまたはva_copyマクロによって初期化されているものとします(同一apの場合は、 が介在してva_endマクロを呼び出すことはありません)。各 のva_argマクロの呼び出しは、 の値が順番に返されるようにapを変更します。パラメータの型は の型名を指定し、指定された型を持つオブジェクト へのポインタの型は* を型付けするだけで取得できます。実際の次の引数がない場合は、タイプが でない場合は、 (デフォルトの引数のプロモーションに応じて昇格されたもの) は未定義です。

  • 一方の型は符号付き整数型であり、もう一方の型は対応する符号なし整数型であり、値は両方とも で表されます。

  • 1つの型はvoidへのポインタであり、もう1つは文字型へのポインタです。

+0

C89はスタンダードCではなく、18年以来旧式です。スタンダードはC11です。 – Olaf

+0

私はC11を反映するために私の答えを更新しました。 –

+0

草案にリンクする場合(最終標準文書にリンクすることはできません)、最終草案(n1570)を使用します。中間文書は使用しません。次回からはもっと慎重にしてください。 – Olaf

1

それは、未定義の動作です。 @Weather Vane

2 2の値とintのタイプ定数進整数です。 2printf(const char * format, ...);...一部に渡されると

それは、この場合にはintintままであるデフォルトの引数のプロモーションを受けます。 printf()2intとして受信します。

"%ld"は、longと一致すると予想します。 longintとして、異なるタイプである:

いずれかの引数が対応する変換仕様の正しいタイプでない場合、動作は未定義です。 C11dr§7.21.6.19

longintのサイズと範囲が同じであっても、結果は依然としてUBである - この点について議論があるが。多くのプラットフォームでは、UBは受け入れられます。いずれにせよ、このコードは避けるべきです。

よく有効になっているコンパイラは、不一致を警告します。

代替:

printf("%d\n", 2); 
printf("%lu\n", 2ul); 
printf("%lu\n", 2UL); 
printf("%lu\n", 1ul * 2); 
printf("%lu\n", (undersigned long) 2); 
+0

ありがとう@chux – user926918

関連する問題