問題

7.20.4.1 最小幅整数定数のマクロ
または ...マクロUINTN_C(value)は、uint_leastN_t型に対応する整数定数式に展開します。たとえば、uint_least64_tunsigned long long int型の名前である場合、UINT64_C(0x123)は整数定数0x123ULLに展開される可能性があります。

UINTN_C()と友人のタイプは期待通りではありません。コード出力の "Expected"コメントを参照してください。

a)私のコンパイラの実装が間違っていて、定数型はuint_leastN_tでなければなりませんか?
または または
または b)UINTN_C(value)の定数の型をuint_leastN_tintunsignedの最小値にし、値をエンコードするために必要な型にする必要がありますか?
または または
または c)他に何か?


定数の型がuint_leastN_tに対応することを期待していましたが、2つの条件ではそうではないようです。

** 1マクロ対応する型がint/unsigned以下の場合、定数はint/unsigned

** 2 値が uint_leastN_t の範囲を超えた場合、型はより広い型定数になります。

更新6.4.4.1 "整数定数の型は、その値を表すことができる対応するリストの最初の型です(長いリストが続きます)。


 #include <limits.h>
#include <stdio.h>

#define type_of(X) _Generic((X), \
  unsigned long long: "unsigned long long", \
  unsigned long: "unsigned long", \
  unsigned: "unsigned", \
  int: "int", \
  unsigned short: "unsigned short", \
  default: "?" \
  )

int main() {
  uint_least16_t u16 = 0;
  uint_least32_t u32 = 0;
  uint_least64_t u64 = 0;
  printf("%zu %s
", sizeof(u16), type_of(u16));
  printf("%zu %s
", sizeof(u32), type_of(u32));
  printf("%zu %s
", sizeof(u64), type_of(u64));
  puts("");
  printf("%zu %s
", sizeof((uint_least16_t) UINT16_C(0)), type_of((uint_least16_t) UINT16_C(0)));
  printf("%zu %s
", sizeof UINT16_C(0), type_of(UINT16_C(0)));
  printf("%zu %s
", sizeof UINT16_C(0x1234), type_of(UINT16_C(0x1234)));
  printf("%zu %s
", sizeof UINT16_C(0x12345), type_of(UINT16_C(0x12345)));
  printf("%zu %s
", sizeof UINT32_C(0x12345678), type_of(UINT32_C(0x12345678)));
  printf("%zu %s
", sizeof UINT32_C(0x123456789), type_of(UINT32_C(0x123456789)));
  return 0;

  //round_frac_test(-2.05446162500000000e+06, 205);
  round_frac_test(fp_rand(), 6);
  round_frac_tests(10000);
  puts("Done");
  return 0;
}
 

出力

 2 unsigned short
4 unsigned
8 unsigned long long

2 unsigned short
4 int       // Expected 2 unsigned short, see **1
4 int       // Expected 2 unsigned short, see **1
4 int       // Expected 2 unsigned short, see **2
4 unsigned
8 unsigned long long  // Expected 4 unsigned, see **2
 

私は(GNU C11(GCC)バージョン5.4.0)を使用しています

この投稿を形成するには、私はBに傾いていますが、私はあなたの合理的な確認方法を探しています。 Bがそうであれば、残念な部分はUINTN_C()が符号付き型になる可能性があるということです。

私はそれが "最小幅"の部分であると思います。

  ベストアンサー

これは親サブセクション7.20.4でカバーされています。

あなたが引用した部分では:

マクロ UINTN_C(value) は、uint_leastN_t 型に対応する整数定数式に展開されます。

拡張が実際にそのタイプであるとは限りません。 「対応する」という意味は、7.20.4p3で説明されています。

これらのマクロのそれぞれの呼び出しは整数に展開されます #if preprocessing ディレクティブで使用するのに適した定数式。 式の型は、 対応する型の式 整数のプロモーション。式の値は、 引き数を返します。

マクロは #if ディレクティブで使用されることを意図しているので、キャストは使用できません(プリプロセッサはキャストや型名を理解していません)。

実際には、このような定数式はほとんど常に適切な型に暗黙的に変換されます。

uint_leastN_tの範囲外の値については、7.20.4p2の親サブセクションでもカバーされています。

これらのマクロのいずれかのインスタンスの引数は、unsuffixed 整数定数(6.4.4.1で定義されている) 対応する型の制限を超えます。

これは制約外の "say"であるため、それに違反すると未定義の動作が発生します。それをしないでください。

(C標準を読むときは、一般的に、あなたが読んでいるものを明確にしたり上書きしたりする文言のために、親サブセクションをチェックすることをお勧めします。私はこれに噛まれました。)

  同じタグがついた質問を見る

clanguage-lawyer