在 C 中,将数组的头指针分配给联合中的现有数组

Assigning an array's head pointer to an existing array in a union, in C

我想要 "equate" 两个数组,其中一个在固定联合内(不应更改)。我不使用 memcpy,而是将 myUnion.RawBytes 的头部指向 array 的头部。但是编译器会为 myUnion.RawBytes = &array[0]; assignmet 抛出错误。为什么会这样?有什么办法可以绕过这个问题吗?

下面的错误代码试图说明这一点。

#include <stdio.h>

typedef union{
    unsigned char  RawBytes[2];
    unsigned short RawWord;
} MyUnion;

int main(){
    MyUnion myUnion;

    char array[2] = {1, 1};
    myUnion.RawBytes = &array[0];

    printf("%d", myUnion.RawWord);

    return 0;
}

错误:

main.c: In function ‘main’:
main.c:12:22: error: assignment to expression with array type
     myUnion.RawBytes = &array[0];

为了解决您的问题,您可以使用以下方法。

Note: Below approach doesn't follow strict aliasing rule.

#include <stdio.h>

typedef union{
    unsigned char  RawBytes[2];
    unsigned short RawWord;
} MyUnion;

int main(){
    MyUnion *myUnion;

    unsigned char array[2] = {1, 1};
    myUnion = &array;

    printf("%d", myUnion->RawWord);
    printf("\n%d %d", myUnion->RawBytes[0], myUnion->RawBytes[1]);

    return 0;
}

我强烈建议你在 union 中使用数组并使用 memcpy 或 for 循环。

双关语的正确做法

#include <stdio.h>

typedef union{
    unsigned char  RawBytes[2];
    unsigned short RawWord;
} MyUnion;

int main(){
    MyUnion myUnion;

    char array[2] = {1, 1};
    myUnion.RawBytes[0] = array[0];
    myUnion.RawBytes[1] = array[1];

    printf("%d", myUnion.RawWord);

    return 0;
}

我读到的问题是 可以使用 any 2 个字符的数组并将其值解释为 unsigned short 而无需复制,通过使用此聪明union把戏,答案是不,你不能

原因是不是严格别名的原因,但它会破坏对齐要求。几乎所有平台对 unsigned short 的对齐要求至少为 2。如果一个指针被转换为另一个没有基本对齐要求的指针,行为是 未定义

是的,这个可以。忘掉能够使用机器语言访问未对齐的对象吧——你是在 C 中编程,而不是在汇编中编程。


正确的方法是使用memcpy告诉编译器访问可以不对齐, 即

char array[2] = {1, 1};
uint16_t raw_word;
memcpy(&raw_word, array, 2);

请注意,memcpy 是一个标准库函数,编译器可以生成 任何 类型的机器代码,只要其行为符合 as if 调用了标准库中的 memcpy 函数。