我有一个这样的示例程序:
#include <stdio.h>
int main()
{
unsigned long long a;
unsigned short b;
b = 10;
*(unsigned short *)&a = b;
printf("a = %lld\n", a);
return 0;
}
我对*(unsigned short *)&a = b;
这行有一个疑问,通常我们在右手边进行类型转换,这里我看到类型转换在左手边。
我看到上面的语句所实现的是,short int
存储在unsigned long long
的LSB位中,unsigned long long
变量中其余位的值可能保持不变。所以像这样的情况我们在左手边做类型转换?
对此有何见解,请分享。
1条答案
按热度按时间owfi6suc1#
由于多种原因,代码具有未定义的行为:
*(unsigned short *)&a = b;
修改a
的初始2个字节实际上具有未定义的行为:如果您正在通过指向非字符类型的不同类型的指针修改a
的值,编译器可能会认为尚未设置a
的值,因为自定义a
以来,未通过类型unsigned long long
执行赋值a
是未初始化的,因此即使前2个字节被修改,剩余的6个字节也是未初始化的,因此将值传递给printf
具有未定义的行为。unsigned long long
类型的值到printf
,它需要一个long long
类型的值。使用%llu
进行无符号转换。下面是一个带有定义行为的修改版本:但是请注意,输出是实现定义的:根据
unsigned short
和unsigned long long
的大小和表示,用b
的字节修改a
的一部分可以产生不同的值,可能是陷阱值,尽管不太可能。在当前的little endian系统上,输出应该是
a = 10
,而在big endian系统上:a = 42949672960
.