Search code examples
cstructcolorsendiannessunions

Can I create color struct that works on different endians?


I am trying to create a union to store my color values channel by channel and 4-byte values at the same time. But I am having problems with the order of channels. Different endian machines give different values. Is there any way to create endian proof version of this struct or use different structs when different endians are better for this job? I want to use structs and unions for educational purposes. I am experimenting and want to learn what can and can't do with C structs.

typedef union u_color
{
    struct
    {
        unsigned char   blue;
        unsigned char   green;
        unsigned char   red;
        unsigned char   alpha;
    };
    unsigned int    value;
}   t_color;

Solution

  • If you want to use it only for getting and setting the value (or getting colours from the value) then (if you use recent gcc family compilers)

    typedef union u_color
    {
      #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
        struct
        {
            uint8_t   blue;
            uint8_t   green;
            uint8_t   red;
            uint8_t   alpha;
        };
      #else
        struct
        {
            uint8_t   alpha;
            uint8_t   red;
            uint8_t   green;
            uint8_t   blue;
        };
      #endif
        uint32_t    value;
    }   t_color;
    

    But for the defining arrays which will represent real screen data structures you need to use one predefined struct layout.

    int main(void)
    {
        t_color x = {.blue = 0x11, .green = 0x22, .red = 0x33, .alpha = 0x44};
        printf("%"PRIx32"\n", x.value);
    }
    

    Will always print 0x11223344 despite the endianness.