C语言volatile修饰结构体指针 两种声明方式为何效果不同?
核心原因
这个问题的根源是typedef封装指针类型时,会改变类型限定符的作用目标,两种声明里volatile修饰的实体完全不同,因此类型检查结果天差地别。
两种声明的本质差异
- 对于
volatile pMyStruct_t pStruct;
你通过typedef定义的pMyStruct_t本身是指向myStruct_t的指针类型,并非结构体类型。这行代码中volatile修饰的是指针变量自身,展开后等价于:
含义是:myStruct_t * volatile pStruct;pStruct这个指针变量本身是volatile的(编译器不会优化对这个指针变量本身的读写操作),但它指向的目标是不带任何限定符的普通myStruct_t类型。
把这个指针传入形参为myStruct_t*的func时,参数是值传递,形参只是实参指针值的副本,指针本身的volatile限定不会影响拷贝后的形参类型,且指针指向的目标类型和形参要求完全匹配,自然不会触发限定符丢弃的编译错误。 - 对于
volatile myStruct_t* pStruct;
这行代码里volatile修饰的是指针指向的目标对象,展开后等价于:
含义是:myStruct_t volatile *pStruct;pStruct是一个普通指针,指向的是带volatile限定的myStruct_t对象。
此时把它传入形参为myStruct_t*的func,相当于把指向volatile myStruct_t的指针隐式转换为指向普通myStruct_t的指针,指向目标的volatile限定被直接丢弃,编译器必然抛出错误——这种转换是类型不安全的,后续通过形参指针访问目标时,编译器会按普通变量做读写优化,完全违背volatile的语义,大概率会引发不符合预期的逻辑错误。
编码提示:尽量不要在typedef中封装指针的
*标记,这种写法会大幅提高const、volatile等类型限定符的误用概率,是C/C++开发中非常经典的易踩坑写法。
内容的提问来源于stack exchange,提问作者Alexey Kiryushkin
相关产品推荐
相关产品推荐

