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

Gul*_*zar 5 c++ endianness

可以说我有以下基于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;
} ;
Run Code Online (Sandbox Code Playgroud)

我有一个包含它们的工会:

union Baz {
    unsigned short val;
    struct Foo foo;
    struct Bar bar;
} ;
Run Code Online (Sandbox Code Playgroud)

然后,在我的程序中,我可以使用val放置一个值,并根据它们的位字段获取a,b,c,d和e值,无需按位操作/接口,并且还需要更多。

但是,问题在于,我需要它同时支持大小端字节序,这意味着我需要在编译时根据字节序来定义位字段。

因此,我需要这样的东西:

#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
Run Code Online (Sandbox Code Playgroud)

我试过查找,发现的所有内容要么是运行时检查,要么是只能在运行时使用的编译值。我知道有很多宏,例如BYTE_ORDER,LITTLE_ORDER,BIG_ORDER等,但是我无法确保它们将在所请求的部署环境以及endian.h标头文件中定义。另外,据我所知,boost的endian.hpp正在实现我上面关于宏所做的描述,因此我不确定它会有所作为。

有什么建议么?


edit1:回应其中的一种评论:我需要一个c ++ 03解决方案,但是一个c ++ 11/14解决方案对于启蒙也是很好的。

Ser*_*eyA 1

对于一个简单的简短问题来说,这个问题太长了:“我如何在编译时知道字节序。”,遗憾的是,这个问题的答案是“你不能”。

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