C99及更高版本中联合体中非const数据能否通过const指针安全访问的技术咨询
C99及更高版本中联合体中非const数据能否通过const指针安全访问的技术咨询
先把你的问题和截断的示例代码补全,你想问的应该是类似下面的场景:
#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> union StringUnion { char* mutable_str; const char* const_str; }; int main() { union StringUnion u; char* buf = malloc(100); if (!buf) return EXIT_FAILURE; strcpy(buf, "Hello, World!"); u.mutable_str = buf; // 核心疑问:通过const_str访问这里的数据是否安全? printf("%s\n", u.const_str); free(buf); return EXIT_SUCCESS; }
明确告诉你:这种访问是完全安全的,不存在未定义、未指定或实现定义的行为,原因如下:
- 从联合体内存规则来看:C99及后续标准规定,联合体的所有成员共享同一块内存空间。当你给
mutable_str赋值后,联合体内存里存储的就是这个char*指针的地址值。通过const_str成员读取时,本质就是读取这块内存里的地址值,再转换为const char*类型。 - 从指针类型转换合理性来看:
char*到const char*的转换是C标准允许的隐式转换——这种转换只是给指针加上了“不能通过该指针修改指向内容”的限制,完全不会改变指针本身的地址值,也不属于类型不兼容的情况,属于标准认可的“安全限定符添加”操作。 - 从访问有效性来看:只要你最后一次写入联合体的是
mutable_str成员,那么通过const_str读取到的指针值就是正确的,只要指向的内存区域(示例里的buf)在访问时处于有效状态(示例中free操作在访问之后,完全合规),就不会有任何问题。
反过来提个醒:如果是先给const_str赋值(比如指向字符串字面量这类只读内存),再通过mutable_str去修改指向内容,那才会触发未定义行为,但你的场景完全相反,所以不用担心。
备注:内容来源于stack exchange,提问作者Eli Minkoff
相关产品推荐
相关产品推荐

