From: david.brown@hesbynett.no   
      
   On 25/11/2025 13:12, Michael S wrote:   
   > On Tue, 25 Nov 2025 11:38:32 +0000   
   > bart wrote:   
   >   
   >>   
   >> No, apart from the usual set of 8/16/32/64 bits. I've done 128 bits,   
   >> and played with 1/2/4 bits, but my view is that above this range,   
   >> using exact bit-sizes is the wrong way to go.   
   >>   
   >   
   > Either that or manifestation of your NIH syndrome.   
   > Which explanation do you consider more likely?   
   >   
   >> While for odd sizes up to 64 bits, bitfields are more apt than   
   >> employing the type system.   
   >>   
   >   
   > int sign_extend12(unsigned x)   
   > {   
   > return (_BitInt(12))x;   
   > }   
   >   
   > Nice, is not it?   
   > Doing the same with bit fields is possible, but less obvious and less   
   > convenient. Also it potentially can play havoc with compiler that took   
   > strict aliasing rules more seriously than they deserve.   
   >   
   > int sign_extend12(unsigned x)   
   > {   
   > struct bar {   
   > signed a: 12;   
   > };   
   > return ((struct bar*)&x)->a;;   
   > }   
   >   
      
   int sign_extend12(unsigned x)   
   {   
    union {   
    struct { unsigned u : 12; };   
    struct { signed s : 12; };   
    } u = {{ x }};   
    return u.s;   
   }   
      
      
   No need for messing about with aliases - type-punning unions are safe   
   and efficient (on good compilers).   
      
   But the _BitInt version is definitely neater. I can see myself using   
   _BitInt(12) and similar sizes for things like values read from hardware   
   sensors of different resolutions.   
      
   (The code for all three is the same with gcc on x86 or arm64 -   
   unfortunately, gcc does not yet support _BitInt on many targets.)   
      
      
   > Doing the same with shifts is almost as convenient as with _BitInt and   
   > it works great on all popular compilers, but according to wording of C   
   > Standard it is Undefined Behavior.   
   >   
   > int sign_extend12(unsigned x)   
   > {   
   > return (int32_t)((uint32_t)x << 20) >> 20;   
   > }   
   >   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|