提问人:pschulz 提问时间:10/22/2022 更新时间:10/22/2022 访问量:68
带指针的 const 结构,丢弃不带警告的限定符
const struct with pointer, discarded qualifier without warning
问:
我有一个带有指向某物的指针的结构。我期望通过指向结构的 const-struct 的指针访问此指针会给我一个指向 const-something 的指针。但在这种情况下,gcc 不会产生警告:
#include <stdlib.h>
struct S {
void* ptr;
};
struct S* create(void)
{
struct S* S = malloc(sizeof(*S));
S->ptr = malloc(sizeof(int));
return S;
}
void some_func(void* p);
int main(void)
{
struct S* S = create();
const void* ptr = S->ptr;
const struct S* SC = S;
some_func(ptr); // warning as expected
some_func(SC->ptr); // no warning
}
所以实际上是一个?我一直以为,但现在我很困惑。在这种情况下是否有可能收到警告?SC->ptr
const void*
答:
SC->ptr
是一个 .它不是 or .void * const
const void *
const void * const
const struct S* SC = S;
定义为指向 -Qualified 的指针。结构是合格的这一事实意味着您不应修改结构。该结构包含 类型的成员。由于结构是 -qualified,因此其成员是 -qualified。这意味着您不应该更改 .其类型为 。SC
struct S
const
const
ptr
void *
const
const
ptr
void * const
但是,这并不影响指向的内容。无论自身是否是 -限定的,它都指向 ,而不是 。ptr
ptr
const
void
const void
C 标准没有提供处理结构的多个版本的好方法,其中一个版本具有指向非类型的成员,而另一个版本具有指向类型的成员。通常,没有好的方法可以将一种这样的结构转换为另一种类型。const
const
评论
那么SC->ptr真的是吗?
const void*
不。 是指定 类型的对象的表达式,不能使用该表达式来修改该对象的值。(原则上,可能有其他表达式指定可以修改它的同一对象。这与 a 类似,但不完全相同 -- 指针不能修改。修改它所指向的数据没有任何意义。SC->ptr
void *
void * const
some_func(SC->ptr); // no warning
[...]
在这种情况下是否有可能收到警告?
C 语义没有提供特别的理由来诊断有关该情况的任何可疑或错误,因为同样,不能修改的是指针,而不是它指向的数据。而且由于指针是按值传递的,因此函数无法对其进行修改。
评论