我想“等同”两个数组,其中一个在固定联合内(不应该更改)。我只是将myUnion.RawBytes
的头部指向array
的头部,而不是使用memcpy。但是编译器会为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];
为了解决您的目的,您可以使用以下方法。
注意:以下方法不遵循严格的别名规则。
#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;
}
我严格建议你在联合内部使用数组并使用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;
}
我读了这个问题,因为可以采取任何2个字符的数组,并通过使用这个聪明的unsigned short
技巧解释它的价值作为union
,没有复制,答案是否定的,你不能。
原因不是严格的混叠,而是它可能违反对齐要求。对于unsigned short
,几乎所有平台都具有至少2的对齐要求。如果指针正在转换为不具有基本对齐要求的另一个指针,则行为未定义。
是的,这可以crash on x86。忘记能够使用机器语言访问未对齐的对象 - 您使用C编程,而不是使用汇编编程。
正确的方法是使用memcpy
,它将告诉编译器访问可以是不对齐的,即
char array[2] = {1, 1};
uint16_t raw_word;
memcpy(&raw_word, array, 2);
请注意,memcpy
是一个标准库函数,只要行为as if调用标准库中的memcpy
函数,就允许编译器生成任何类型的机器代码。