On 2026-03-14 Paul Eggert wrote:
> On 2026-03-14 05:04, Bruno Haible wrote:
> 
> > here, clearly, everyone
> > is assuming that
> >     uint8_t == 'unsigned char' has 8 bits,
> >     uint16_t == 'unsigned short' has 16 bits,
> >     uint32_t == 'unsigned int' has 32 bits,
> >     uint64_t == 'unsigned long long' has 64 bits,
> >     and two's complement.  
> 
> That depends on what is meant by "here". Yes, in parts of Gnulib we 
> assume that. However, stdbit.in.h doesn't assume that anywhere, not
> even in the byteswap.in.h that it sometimes includes. The only place
> those types appear is in a stdbit.in.h comment. Come to think of it,
> that comment's types should be changed to match the code; done in the
> first attached patch.

It's just a comment, but if a platform exist where CHAR_BIT == 8 and
uint16_t is missing, then uint_least16_t has padding bits and
sizeof(uint_least16_t) > 2. Then the memcpy method doesn't initialize
the variable fully because it only copies two octets:

-     uint16_t
+     uint_least16_t
      load16_e (const unsigned char ptr[2])
      {
-       uint16_t value;
+       uint_least16_t value;
        memcpy (&value, ptr, 2);
        return value;
      }

But it obviously shouldn't copy more than 2 either. It seems that the
memcpy method isn't usable in this case, and ideally the code would
fail to compile.

If CHAR_BIT == 8 and uint_least16_t has no padding bits, then
sizeof(uint_least16_t) == 2. When a 16-bit wide unsigned type with no
padding bits exists, then uint16_t must exist too (C99 7.18.1.1p3 or
C23 7.22.1.1p3).

Thus, if the memcpy examples used exact-width types for "value", then
the code would compile if CHAR_BIT == 8 && sizeof(uint_least16_t) == 2,
and otherwise fail to compile. The return type can still be a _leastN_t.

-- 
Lasse Collin

Reply via email to