の整数変換ランクは(6.3.1.1p1)longのランクよりも大きい必要があるため、と同じ表現(および精度)を持っている場合でも必要です。ほとんどの64ビットプラットフォームでは、64ビットであることに注意してください。Windows(LLP64プラットフォーム)は例外です。intva_arg(args, long) longintlong
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で許可されています)。intsize_tintunsigned intva_arg(args, unsigned int)size_tint
- と同じです。
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_tunsigned intunsigned intunsigned intunsigned intdefaultsize_tsize_tunsigned int
これはに限定されない問題size_tでptrdiff_tありwchar_t、同じ問題があることに注意してください(後者の場合、wint_t任意のwchar_t値を保持でき、昇格の対象にはなりませんが、に昇格される保証とはwchar_t 異なりwint_t、に昇格される保証はありません)。標準では、新しいタイプ、、、およびを導入する必要があることをお勧めします。同様に、のタイプについても同様です。(もちろん、上記のように使用できますが、首が痛いです。)charintspromo_tppromo_twpromo_tstdint.h_Generic