C++では32ビット環境でも64ビット環境でもuint32_tとDWORDは32ビット整数型ですが、歴史的経緯1から区別されます。C++20では関数テンプレ―トによりこれらを同一視できます。
# include <cstdint> // int32_t, uint32_t, int16_t, uint16_t
# include <type_traits> // is_integral_v
# define STRICT
# include <Windows.h> // DWORD, ULONG, WORD, SHORT
using namespace std;
template <typename T>
T f(T x)
{
static_assert(is_integral_v<T> && sizeof(T) == 4, "32ビット整数を指定してください。");
return x;
}
int main()
{
// uint32_tとDWORDはコンパイル時に32ビット整数なので何も起きません。
f(uint32_t(0));
f(DWORD(0));
// f(uint16_t(0)); // 16ビット。static_assertでコンパイルエラー
// f(WORD(0)); // 16ビット。static_assertでコンパイルエラー
// 符号は確認しないので符号付きでも同様です。
f(int32_t(0));
f(ULONG(0));
// f(int16_t(0)); // 16ビット。static_assertでコンパイルエラー
// f(SHORT(0)); // 16ビット。static_assertでコンパイルエラー
return 0;
}
主要な部分は以下の一文です。std::is_integral_v<T>
で整数型、sizeof(T) == 4
で32ビット(4バイト)であることを確認しています。static_assert
は条件式がfalse
の場合にコンパイルエラーを発生します。メッセージは省略できます。
static_assert(is_integral_v<T> && sizeof(T) == 4, "32ビット整数を指定してください。");
-
int
は16ビット環境では16ビット整数でした。現在でもshort int
に名残があります。 ↩