根据机器的字节顺序定义宏

问题描述 投票:-1回答:4

我想根据机器的字节顺序在结构中定义变量,这就是我尝试过的

#define IS_BIG_ENDIAN (!(union { uint16_t u16; unsigned char c; }){ .u16 = 1 }.c)
//#define IS_BIG_ENDIAN (!*(unsigned char *)&(uint16_t){1})
struct A {
    #if IS_BIG_ENDIAN
    char a:4;
    char b:4;
    #else
    char b:4;
    char a:4;
    #endif
}

上面的代码给出了错误,这是可能实现的。我的主要目标是实现结构变量的逆序。

c++ c++11 endianness
4个回答
2
投票

来自https://sourceforge.net/p/predef/wiki/Endianness/

你没有标准的方法来拥有它。

但自定义标题<sys/param.h><endian.h>可能会提供MACRO,例如:

Type                            Macro           Value
Big endian                      __BYTE_ORDER    __BIG_ENDIAN
Little endian                   __BYTE_ORDER    __LITTLE_ENDIAN
Little endian (word-swapped)    __BYTE_ORDER    __PDP_ENDIAN

1
投票

等到C ++ 20(或使用编译器的实验性功能),您将能够使用C ++标准std::endian

表示所有标量类型的字节顺序:

如果所有标量类型都是little-endian,则std :: endian :: native等于std :: endian :: little如果所有标量类型都是big-endian,则std :: endian :: native等于std :: endian :: big


1
投票

该测试不适用于预处理器if-directive。

即将推出的C ++ 20被提议拥有std::endian。它可以在没有预处理器的情况下使用。

static_assert(std::endian::native == std::endian::big
           || std::endian::native == std::endian::little);

struct ABig {
    char a:4;
    char b:4;
};

struct ALit {
    char b:4;
    char a:4;
};

using A = std::conditional_t<std::endian::native == std::endian::big, ABig, ALit>;

在C ++ 20之前,没有获得字节序的标准方法。

便携式解决方案是使用预定义的宏来检测系统。有些系统是小端(Windows),而其他系统提供带有宏定义的标头(Linux中的<endian.h>,BSD中的<sys/endian.h>等),其他系统可能在某些其他方面有所不同。 GCC编译器提供宏:

__BYTE_ORDER__
__ORDER_LITTLE_ENDIAN__
__ORDER_BIG_ENDIAN__
__ORDER_PDP_ENDIAN__

也就是说,位域表示的几乎每个方面都是实现定义的,如果顺序很重要 - 就像它看起来那样 - 那么你将不得不依赖于特定的实现,所以便携性是不可能实现的。确定目标系统,一旦确定,请查阅该系统的文档,了解如何获得字节序。

最好不要依赖位域的表示。


-1
投票

谢谢@ Jarod42,以下代码对我有用

#define IS_BIG_ENDIAN !(__BYTE_ORDER__- __BIG_ENDIAN)
struct A {
    #if IS_BIG_ENDIAN
    char a:4;
    char b:4;
    #else
    char b:4;
    char a:4;
    #endif
};
© www.soinside.com 2019 - 2024. All rights reserved.