https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88895
--- Comment #6 from Martin Sebor <msebor at gcc dot gnu.org> --- The C++ solution to this kind of problem is to use template specialization. It's a been a while since I wrote any real C++ code but this seems to work and avoids the warnings class PackRule { template <class T, unsigned N> struct Packer; public: const unsigned short offset_; const unsigned char width_; inline PackRule(const unsigned short offset, const unsigned char width) : offset_(offset), width_(width) {} template <typename T> inline void pack (void* to, const T v) const { unsigned char* tobyte = (unsigned char*)to + offset_; Packer<T, sizeof (T)>::pack (tobyte, v); } template<typename T> inline T unpack (const void* from, T* output) const { const unsigned char* frombyte = (const unsigned char*)from + offset_; return *output = Packer<T, sizeof (T)>::unpack (frombyte); } }; template <class T, unsigned N> struct PackRule::Packer { static void pack (unsigned char *p, T x) { p[sizeof (T) - N] = (unsigned char)(x >> (N - 1) * __CHAR_BIT__); Packer<T, N - 1>::pack (p, x); } static T unpack (const unsigned char *p) { T x = (0xffU & (T)p[sizeof(T) - N]) << ((N - 1) * __CHAR_BIT__); return x | Packer<T, N - 1>::unpack (p); } }; template <class T> struct PackRule::Packer<T, 0> { static void pack (unsigned char*, T) { } static T unpack (const unsigned char*) { return T (); } }; int main () { PackRule p(0, 4); unsigned char buf[4]; p.pack (buf, (unsigned int)444); unsigned int t; p.unpack (buf, &t); }