我今天在工作中遇到了一个关于结构体中 const 传播的问题。 当我遇到两个不同的编译器(GCC 和 IAR)不一致的问题时,我试图向旧代码添加一些 const 正确性。 我认为这可以归结为向结构变量添加 const 是否会使指针成员成为
<type>* const
或 const <type>* const
。
最小示例:
struct S
{
char* p;
};
void f(const struct S* s)
{
char* non_const_char = s->p;
*non_const_char = 'a'; // Modyfing data that could be argued being part of const struct
}
GCC 允许此代码,但 IAR 失败并表示无法进行分配 non_const_char,因为
“char const *”类型的值不能分配给“char *”类型的实体
根据多个SO问题,GCC是正确的,例如用于保护C中结构的底层成员的指针的“const”范围。 这也得到了cppreference的证实。
但是,我的标准语言不够流利,无法解析标准的哪一部分实际上说 const 限定传播到结构成员,但不传播到成员指针指向的类型。谁能告诉我/引用哪一部分说明了这一点?不同的标准版本有没有改变过?
C17 标准第 6.7.3 节 规定:
如果尝试通过使用 const 限定类型来修改定义的对象 具有非 const 限定类型的左值,行为未定义。
在您的示例中,修改
s->p
是未定义的行为,因为它是 const 限定类型的对象的一部分。然而,p
指向的内存并不是s
本身的一部分,因此你可以修改它。