c – 在编译时根据字节顺序定义位域

假设我有以下2个基于2个字节的结构:

#pragma pack(1)
struct Foo {
    unsigned short a : 5;
    unsigned short b : 4;
    unsigned short c : 2;
    unsigned short d : 5;
} ;

struct Bar {
    unsigned short a : 5;
    unsigned short b : 4;
    unsigned short c : 2;
    unsigned short d : 3;
    unsigned short e : 2;
} ;

我有一个包含它们的联盟:

union Baz {
    unsigned short val;
    struct Foo foo;
    struct Bar bar;
} ;

然后在我的程序中,我可以使用val来设置一个值,并根据它们的位域获得a,b,c,d和e值,不需要按位操作/接口.

但问题是,我需要它支持大端和小端,这意味着我需要让我的struct根据编译时的字节顺序定义位域.

因此,我需要这样的事情:

#pragma pack(1)
#if BIG_ENDIAN
struct Foo {
    unsigned short a : 5;
    unsigned short b : 4;
    unsigned short c : 2;
    unsigned short d : 5;
} ;

struct Bar {
    unsigned short a : 5;
    unsigned short b : 4;
    unsigned short c : 2;
    unsigned short d : 3;
    unsigned short e : 2;
} ;

#else
struct Foo {
    unsigned short d : 5;
    unsigned short c : 2;
    unsigned short b : 4;
    unsigned short a : 5;
} ;

struct Bar {
    unsigned short e : 2;
    unsigned short d : 3;
    unsigned short c : 2;
    unsigned short b : 4;
    unsigned short a : 5;
} ;
#endif

我试着查看它,我能找到的只是运行时检查或编译值,只能在运行时使用.
我知道有许多宏,如BYTE_ORDER,LITTLE_ORDER,BIG_ORDER等,但我不能确保它们将在请求的部署环境中定义,以及endian.h头文件.另外,据我所知,boost的endian.hpp正在实现我上面提到的关于宏的内容,所以我不确定它会有什么不同.

有什么建议?

EDIT1:
回答其中一条评论:我需要一个c 03解决方案,但是一个c 11/14一个也很适合启蒙.

最佳答案 对于一个简单的简短问题,这个问题太长了:“如何在编译期间知道endiannes.”,遗憾的是,这个问题的答案是“你不能”.

问题是,Posix和C/C++标准都没有指定关于字节序的任何内容.您唯一能做的就是测试已知的特定于体系结构的宏并从中派生出enddiannes.

点赞