在ANSI C中使用union将四个uint8_t的数组转换为uint32_t

在ANSI C中使用union将四个uint8_t的数组转换为uint32_t,c,arrays,union,c99,C,Arrays,Union,C99,我正在研究XC8(微芯片8位微控制器的C编译器,可能基于gcc)中的一些代码 我使用了许多字节数组->任意和任意->字节数组转换,如下所示: inline int32_t GetInt32(uint8_t b3, uint8_t b2, uint8_t b1, uint8_t b0) { int32_t b_31_24 = (((int32_t)b3) << 24); int32_t b_23_16 = (((int32_t)b2) << 16);

我正在研究XC8(微芯片8位微控制器的C编译器,可能基于gcc)中的一些代码

我使用了许多字节数组->任意和任意->字节数组转换,如下所示:

inline int32_t GetInt32(uint8_t b3, uint8_t b2, uint8_t b1, uint8_t b0)
{
    int32_t b_31_24 = (((int32_t)b3) << 24);
    int32_t b_23_16 = (((int32_t)b2) << 16);
    int32_t b_15_08 = (((int32_t)b1) << 8);
    int32_t b_07_00 = b0;

    return b_31_24 + b_23_16 + b_15_08 + b_07_00;        
}
我想减少CPU和/或内存使用。

让我们假设:

  • 此代码将与同一编译器一起使用
  • 我知道endiannes是什么,没有我的知识,它不会改变:)
  • 我知道不同的编译器在对齐方面可能有不同的行为(我测试过微芯片XC8、XC32和一些STM编译器)
我为什么要问这个问题?

typedef union {
    int32_t int32value;
    uint32_t uint32value;
    int16_t[2] int16words;
    uint16_t[2] uint16words;
    int8_t[4] int8bytes;
    uint8_t[4] uint8bytes;
} union32_t;

我想确定的是,在将
字节数组
转换为
int
等时,如果数组没有像“未定义行为”这样的问题。

联合双关是100%好的。根本没有问题(endianes除外)

你所做的就是邀请编译器烧毁你的房子。现代C语言不适用于像这样的低级编程。@mevets谁告诉你的?不要再信任这个人了……@P_uuj_uuu:clang和gcc优化器所青睐的“现代C”类型只适用于那些只在它们永远不会恶意构建数据的环境中运行的应用程序,或者它们可能做的任何事情(甚至恶意)都不会产生任何不可接受的后果。但是谁说任何人都应该使用“现代C”?只要你在这个过程中不违反任何其他规则就可以了。当然,这会有助于您了解如何使用union的示例。实际上,gcc开发人员更喜欢union双关。关于它的讨论由来已久。尽管标准将
someUnion.array[x]
的含义定义为
*((someUnion.array)+(x))
,但后一种形式在gcc和clang中是不可靠的。标准将第一种形式定义为等同于第二种形式。在使用第二种形式时,gcc和clang都不能可靠地适应类型双关,即使使用标准指定的与第一种形式等效的确切语法也是如此。gcc的文件中是否有任何内容表明这两种形式是不等价的,没有对其中一种形式进行有意义的处理并不意味着另一种形式不应被视为可靠的?您无法证明您的主张。这只是你的观点,数百万开发者并不认同。gcc和clang并不认为这些构造是等价的,这一事实在godbolt中很容易证明。标准将其定义为等效的事实是N1570 6.5.2.1第2段。你不同意哪一部分?