C中常量到非常量的赋值

C中常量到非常量的赋值,c,constants,void-pointers,C,Constants,Void Pointers,在以下方面: struct adt { void * A; }; int new_adt(const void * const A) { struct adt * r = malloc(sizeof(struct adt)); r->A = A; } 我得到: 警告:分配将丢弃指针目标类型中的限定符 我知道我可以用 memcpy(&(r->A), &A, sizeof(void *)); 但我必须问:还有其他选择吗 通过使用const void

在以下方面:

struct adt { void * A; };

int new_adt(const void * const A)
{
    struct adt * r = malloc(sizeof(struct adt));
    r->A = A;
}
我得到:

警告:分配将丢弃指针目标类型中的限定符


我知道我可以用

memcpy(&(r->A), &A, sizeof(void *));
但我必须问:还有其他选择吗

通过使用
const void*const
我假装不会对输入进行任何更改。而且,现在我想起来,
const void*
就足够了,不是吗?(因为我无法更改指针以使其影响调用者)


感谢您花时间阅读。

如果您永远不想通过
adt
中的指针修改
A
,那么您也应该将该指针设置为常量,即:

struct adt {
    const void * A;
};
这将使错误消失

如果确实要通过
adt
修改
A
,则
new\u adt
应采用非常量指针


编辑:更一般的注释,可能有助于:

通常,
const
关键字应用于紧靠其左侧的类型。但是,如果左侧没有类型,它将应用于右侧的类型。因此:
常数int*A
常数int*A
相同(常数
适用于
int
,而不是指针),但在
int*const A
中,常数适用于指针,而不是int


维基百科上有一个更全面的解释:。该页面的“指针和引用”部分包括一个示例,其中介绍了可应用于指针的常量和非常量的各种组合。

您可以丢弃常量:

r->A = (void *) A;
然而,问题不在于如何避免警告,而在于你试图做什么。编译器警告您,因为您告诉编译器“A”不可写,但您试图将其存储在定义为可写的位置。从语义上来说,这通常是不好的

假设“A”指向二进制文件数据部分中的一个位置;在抛出const之后,试图写入它,很可能会导致segfault

所以,真的,在尝试解决编译器警告之前,请仔细考虑您要做的事情。它们是有充分理由的警告

通过使用const void*const,我假装不会对输入进行任何更改

您没有假装说不会对输入进行任何更改,而是明确地告诉编译器您已保证不会对输入进行任何更改


你不能做你正在做的事。

你在哪里声明的
r
?它的类型是什么?谢谢,但我确实理解了:我想在将来替换
A
的值,就像在
void replace(const void*const A,struct adt*r){r->A=A;}
中一样。这是通过
adt
修改
A
的值吗?
const void*A
(或者,等价地,
void const*A
)意味着您可以将
A
更改为指向其他地方,但不能更改
A
指向的内容。因此,您仍然可以毫无问题地执行
r->A=new\u A