yohhoyの日記

技術的メモをしていきたい日記

bit_castマクロ for C言語

プログラミング言語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