Search code examples
cgccportabilityendiannessbit-fields

How to properly use gcc -fsso-struct for portable programs?


I am trying to use gcc option -fsso-struct to set portably bit-fields layouts (I think it is a gcc-6 features https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html).

Currently, I have two sets of bit-fields structures : one for big endian and one for little endian. I use the BYTE_ORDER flag to choose one or the other (https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html).

I set alternatively -fsso-struct to big and little endian but I don't see the difference in interpreting the bit-fields. How should I use it ?


Solution

  • Look at the warning in the documentation:

    Warning: the -fsso-struct switch causes GCC to generate code that is not binary compatible with code generated without it if the specified endianness is not the native endianness of the target.

    Any option with such a warning is an option that you should not be using if you're interacting with any library, even the standard library.


    This option is also available in a local form, which can be used safely through a #pragma directive. These functions:

    struct A { int i; };
    #pragma scalar_storage_order big-endian
    struct B { int i; };
    #pragma scalar_storage_order little-endian
    struct C { int i; };
    #pragma scalar_storage_order default
    struct D { int i; };
    
    int fa(struct A a) { return a.i; }
    int fb(struct B b) { return b.i; }
    int fc(struct C c) { return c.i; }
    int fd(struct D d) { return d.i; }
    

    cause struct A and struct D to have the platform's default endianness, struct B to be big endian, and struct C to be little endian. As a result, fa, fd, and either fb or fc, can be compiled to code that simply loads the value directly from the parameter. The remaining function, either fc or fb, will contain code to swap the bytes.

    As you can see, this option is not about bit-fields. It does affect bit-fields too, but that's only because bit-fields store integer values, and this option affects integer storage.