为何&d1->b = d2报赋值左值错误而d1=(void*)d2无编译错误
C语言赋值错误原因分析
语法报错核心原因
&d1->b = d2;报错的本质是违反了C语言的赋值语法规则:
- 赋值运算符
=的左操作数必须是可修改的左值,左值指代一块可被写入的、固定的内存空间,普通变量、指针变量都是典型的左值。 - 取地址运算符
&的返回结果是右值:&d1->b是计算得到的d1结构体成员b的地址数值,属于临时生成的中间值,没有对应的可写入内存空间,和常量数值的性质完全一致,自然不能放在赋值号左侧被赋值。
合法赋值的原因
d1 = (void *)d2;符合C语言语法规则:
- 左操作数
d1是struct s1类型的指针变量,本身就是可修改的左值,它在内存中有独立的存储空间,支持修改它存储的地址值。 - C语言允许
void*类型指针隐式转换为任意其他类型的指针,将d2强转为void*后赋值给d1的操作完全符合语法要求,因此编译器不会报错。
补充说明
- 你的原有认知存在偏差:默认字节对齐规则下,
struct s2仅包含2个uint8_t成员,总大小为2字节,并非你认为的32位(4字节)。 - 示例代码存在逻辑问题:
d1、d2都是未初始化的野指针,直接解引用修改成员的操作,运行时一定会触发内存访问错误。 - 如果你的需求是让
d2指向d1->b的存储空间,正确写法为:
d2 = (struct s2 *)&d1->b;
内容的提问来源于stack exchange,提问作者Giri Kishore
相关产品推荐
相关产品推荐

