STLはsize_t
、Win32 APIはDWORD
(あるいはUINT
)を使う場合が多いです。size_t
からDWORD
へは暗黙にキャストできますが、範囲外が切り捨てられる可能性があるのでコンパイル警告が発生します。Cスタイルキャスト(DWORD)...
やキャスト演算子static_cast<DWORD>(...)
により警告を消せますが、切り捨ての可能性については念頭に置くべきです。
次のコードでは64ビット環境のsize_t
と同サイズのstd::uint64_t
をDWORD
と同サイズのstd::uint32_t
へstatic_cast
しています。キャスト前後の値が異なること(0x12345678ABCDEF12 != (std::uint32_t)0x12345678ABCDEF12 == 0xabcdef12
)に注意してください。
#include <cstdint> #include <iostream> int main() { std::uint64_t ui64 = 0x12345678ABCDEF12; std::uint32_t ui32 = static_cast<std::uint32_t>(ui64); std::wcout << L"0x" << std::hex << ui64 << std::endl; std::wcout << L"0x" << std::hex << ui32 << std::endl; // > 0x12345678abcdef12 // > 0xabcdef12 }
符号ありほど大きな問題は生じませんが、size_t
とDWORD
を意図せず混在させるとバグの余地が残ることが推察されます。問題の解決にはビット演算や<numeric>
のnumeric_limits<DWORD>::max()
による変換前の確認、Boost C++ Librariesのnumeric_cast
の使用などが挙げられます。
なお、DWORD
を扱うWin32 APIのみ使用する場合など、限定的な状況ではstatic_cast
を使用しても問題は生じません。