Skip to content

Commit 2aafe7c

Browse files
serialization: Don't use a union for type punning (undefined behaviour)
1 parent be99270 commit 2aafe7c

File tree

1 file changed

+16
-12
lines changed

1 file changed

+16
-12
lines changed

src/serialize.h

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -126,27 +126,31 @@ template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
126126
}
127127
inline uint64_t ser_double_to_uint64(double x)
128128
{
129-
union { double x; uint64_t y; } tmp;
130-
tmp.x = x;
131-
return tmp.y;
129+
static_assert(sizeof(uint64_t) == sizeof(double), "Floating-point width assumption");
130+
uint64_t y;
131+
memcpy(&y, &x, sizeof(y));
132+
return y;
132133
}
133134
inline uint32_t ser_float_to_uint32(float x)
134135
{
135-
union { float x; uint32_t y; } tmp;
136-
tmp.x = x;
137-
return tmp.y;
136+
static_assert(sizeof(uint32_t) == sizeof(float), "Floating-point width assumption");
137+
uint32_t y;
138+
memcpy(&y, &x, sizeof(y));
139+
return y;
138140
}
139141
inline double ser_uint64_to_double(uint64_t y)
140142
{
141-
union { double x; uint64_t y; } tmp;
142-
tmp.y = y;
143-
return tmp.x;
143+
static_assert(sizeof(double) == sizeof(uint64_t), "Floating-point width assumption");
144+
double x;
145+
memcpy(&x, &y, sizeof(x));
146+
return x;
144147
}
145148
inline float ser_uint32_to_float(uint32_t y)
146149
{
147-
union { float x; uint32_t y; } tmp;
148-
tmp.y = y;
149-
return tmp.x;
150+
static_assert(sizeof(float) == sizeof(uint32_t), "Floating-point width assumption");
151+
float x;
152+
memcpy(&x, &y, sizeof(x));
153+
return x;
150154
}
151155

152156

0 commit comments

Comments
 (0)