プログラミング言語Cにおいて、ビット表現を維持したまま型変換を安全に行うマクロ。C++標準ライブラリのstd::bit_cast<To>(from)相当。
本記事の内容はStackOverflowで見つけた質問と回答に基づく。
// C99 : 右辺値に未対応 #define bit_cast(T, ...) \ (*((T*)memcpy(&(T){0}, &(__VA_ARGS__), sizeof(T)))) // C23 #define bit_cast(T, ...) \ ((union{typeof(T) a; typeof(__VA_ARGS__) b;}) {.b=(__VA_ARGS__)}.a) // または #define bit_cast(T, ...) \ (*(typeof(T)*)memcpy(&(T){0}, &(typeof(__VA_ARGS__)) {(__VA_ARGS__)}, sizeof(T)))
式static_assert(→id:yohhoy:20250905)を利用して型サイズ検査を組み込んだバージョン:
// C23 #define bit_cast(T, ...) \ ((union{typeof(T) a; typeof(__VA_ARGS__) b; \ static_assert(sizeof(T)==sizeof(__VA_ARGS__));}) \ {.b=(__VA_ARGS__)}.a) // C11 #define bit_cast(T, ...) \ ((void)sizeof(struct{int dummy_member; \ _Static_assert(sizeof(T) == sizeof(__VA_ARGS__), "");}), \ *((T*)memcpy(&(T){0}, &(__VA_ARGS__), sizeof(T)))) // #include <assert.h>でstatic_assertと記述可能
関連URL
- cppreference bit_cast, cpprefjp bit_cast
- typeof演算子 in 標準C - yohhoyの日記
- 式static_assert in C言語 - yohhoyの日記