On Thursday, July 30, 2020 at 10:36:49 AM UTC+1, Bo Persson wrote:
> or (D) Don't use an older library when there is an new and improved one
I work with the scraps that I'm given. My orders come from a guy who gets 150% my salary, who gets his orders from a guy who gets 150% his salary (so that's 225% my salary).
If the guy getting 2.25 times my salary tells my boss that the arm32 product uses Library v1.0.1, and that the aarch64 product uses Library v1.0.4, then I run with that.
> Note that the ISO standard doesn't require a compiler to have 8, 16, or
> 32 bit integer types, and doesn't say what size a float is. Or if there
> are padding between members. So this is totally non-portable anyway.
99% of architectures have 8-bit bytes and integer types of size 16-Bit and 32-Bit (without padding inside the integer type). I'm not saying that the 1% don't exist, but they're probably in a museum.
> And it definitely doesn't give any meaning to
>
> reinterpret_cast<u8*>(p_z + 1u)
This line of code has very understandable meaning on computers where all pointers are the same size. And even on a computer where a pointer to a byte is bigger (because it's a pointer + offset), the conversion to u8* will add in that offset for me.
> The only portable way to set the transparent bit is
>
> e.transparent = 1;
Again, I work with the scraps I'm given.
> If you just *have* set a byte in the reserved area, you could do
>
> #if defined SOME_OLD_SYSTEM
> e.reserved[0] = transparent_hack_value;
> #endif
I don't want to wipe out any other stuff stored in "reserved", plus I don't want to make assumptions about endianness (because our ARM products are Big-Endian, and our x86 products are Little-Endian). If I was going with your method then I'd do something like:
u32 constexpr high = is_big_endian ? 0x80000000 : 0x00000080;
u32 constexpr low = is_big_endian ? 0x01000000 : 0x00000001;
u32 constexpr transparent_value = is_bitfield_left_to_right ? high : low;
e.reserved[0] |= transparent_value;
But I think it would be preferable just to access one byte like this:
*reinterpret_cast<char unsigned*>(e.reserved) |= left_to_right ? 0x80 : 0x01;
In the end however I decided to go with:
void Set_Flag_For_Transparency(Manager &e)
{
typedef struct {
u16 scale;
u8 window;
u8 a;
u8 b;
u8 c;
float x;
float y;
float z;
s8 offset;
u8 transparent : 1;
u8 reserved0 : 7;
u8 reserved1[2];
u32 reserved2[3];
} Manager;
Latest_Rendition_Of_Struct *const p = reinterpret_cast<Latest_Rendition_Of_Struct*>(&e);
p->transparent = 1;
}