の整数変換ランクは(6.3.1.1p1)long
のランクよりも大きい必要があるため、と同じ表現(および精度)を持っている場合でも必要です。ほとんどの64ビットプラットフォームでは、64ビットであることに注意してください。Windows(LLP64プラットフォーム)は例外です。int
va_arg(args, long)
long
int
long
size_t
符号なし整数型(6.5.3.4p5、7.19p2)である必要があり、整数変換ランクがlong int
(7.19p4)以下であることが推奨されます。少なくとも16ビット(7.20.3p2、最小値SIZE_MAX
)の精度が必要です。(typedefからa)標準整数型である必要はありませんが、可能です。
その場合、整数変換ランクには3つの可能性がありますsize_t
。
- の精度よりも小さい
int
ため、引数は(の精度がの精度よりも低い場合)または(2つのタイプの精度が同じ場合)のsize_t
いずれかに昇格されます。いずれの場合も、書き込む必要があります(引数がにプロモートされている場合でも、同等の符号なし型の使用は7.16.1.1p2で許可されています)。int
size_t
int
unsigned int
va_arg(args, unsigned int)
size_t
int
- と同じです。
int
つまりsize_t
、と同じタイプunsigned int
です。この場合、va_arg(args, unsigned int)
またはva_arg(args, size_t)
が許可されます。
- のそれよりも大きいです
int
。この場合va_arg(args, size_t)
、を使用する必要があります。
size_t
の精度がと同じであっても、1と3のどちらでも取得できることに注意してくださいint
。
これは、をsize_t
使用してパラメータを抽出するva_arg
には、の整数変換ランクを知るか推測する必要があることを意味しますsize_t
。これは、型ジェネリックマクロ(6.5.1.1)を使用して実行できます。
#define va_arg_size_t(args) _Generic((+(sizeof(0))), \
int: (size_t) va_arg((args), unsigned int), \
unsigned int: (size_t) va_arg((args), unsigned int), \
default: va_arg((args), size_t))
size_t
上記のように単項プラス演算子によって昇格された場合、 ;int
を抽出します。にプロモートされているunsigned int
場合、またはにtypedefである場合は、 ;を抽出します。昇格せず、とは異なるタイプの場合は、ブロックにヒットします。のtypedefである場合は競合するため、オプションとしてそれ自体を提供することはできません。size_t
unsigned int
unsigned int
unsigned int
unsigned int
default
size_t
size_t
unsigned int
これはに限定されない問題size_t
でptrdiff_t
ありwchar_t
、同じ問題があることに注意してください(後者の場合、wint_t
任意のwchar_t
値を保持でき、昇格の対象にはなりませんが、に昇格される保証とはwchar_t
異なりwint_t
、に昇格される保証はありません)。標準では、新しいタイプ、、、およびを導入する必要があることをお勧めします。同様に、のタイプについても同様です。(もちろん、上記のように使用できますが、首が痛いです。)char
int
spromo_t
ppromo_t
wpromo_t
stdint.h
_Generic