lundi 3 juillet 2023

Inconsistent results when type punning uint64_t with union and bit-field

I am using an anonymous struct in union as follows:

using time64_t = uint64_t;
using bucket_t = uint64_t;

union clock_test {
    time64_t _time64;

    struct {
        bucket_t _bucket5 : 10;     // bucket:5  1024
        bucket_t _bucket4 : 8;      // bucket:4  256
        bucket_t _bucket3 : 6;      // bucket:3  64
        bucket_t _bucket2 : 6;      // bucket:2  64
        bucket_t _bucket1 : 6;      // bucket:1  64
        bucket_t _bucket0 : 6;      // bucket:0  64
    };
};

If bucket_t = uint64_t, it works as expected, but with using bucket_t = uint16_t or uint32_t, I get puzzling results.

I use the same test code for all cases:

clock_test clk;
clk._time64 = 168839113046;

For bucket_t = uint64_t, clk is:

_bucket5   342  // unsigned __int64
_bucket4    26  // unsigned __int64
_bucket3    38  // unsigned __int64
_bucket2    15  // unsigned __int64
_bucket1    29  // unsigned __int64
_bucket0     2  // unsigned __int64

For bucket_t = uint32_t, clk is:

_bucket    342  // unsigned int
_bucket4    26  // unsigned int
_bucket3    38  // unsigned int
_bucket2    15  // unsigned int
_bucket1    39  // unsigned int
_bucket0     0  // unsigned int

For bucket_t = uint16_t, clk is:

_bucket5    342 // unsigned short
_bucket4    152 // unsigned short
_bucket3     15 // unsigned short
_bucket2     39 // unsigned short
_bucket1      0 // unsigned short
_bucket0      0 // unsigned short

Aucun commentaire:

Enregistrer un commentaire