在C中将const赋值给非const

时间:2011-02-10 23:38:03

标签: c const 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 * const我假装说不会对输入进行任何更改。而且,现在我想起来了,const void *就足够了,不是吗? (因为我无法更改指针以使其影响调用者)

感谢您花时间阅读。

3 个答案:

答案 0 :(得分:7)

  

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

假装 表示不会对输入进行任何更改,您已明确告诉编译器您已< strong> 保证 不会对输入进行任何更改。

做你正在做的事情。

答案 1 :(得分:5)

如果你永远不想通过A的指针修改adt,那么你也应该那个指针const,即:

struct adt {
    const void * A;
};

这将使错误消失。

如果你想要通过A修改adt,那么new_adt应该采用非常量指针。


编辑:更一般的说明,这可能会有所帮助:

const关键字通常适用于 left 的类型。但是,如果左侧没有类型,则它将应用于右侧的类型。所以: const int * Aint const * A相同(const适用于int,而不适用于指针),但在int * const A中,const适用于指针,而不是int。

维基百科有一个更全面的解释:const-correctness。该页面的“指针和引用”部分包含一个示例,其中包含可应用于指针的const和非const的各种组合。

答案 2 :(得分:0)

你可以抛弃const:

r->A = (void *) A;

但问题不在于如何避免警告,更多的是关于你想要做什么。编译器警告你,因为你告诉编译器“A”不可写,但你试图将它存储在一个定义为可写的位置。从语义上讲,这通常不行。

想象一下,“A”指向二进制数据部分中的某个位置;尝试写入它后,将const转换掉,最有可能导致段错误。

所以,实际上,在尝试解决编译器警告之前,请考虑一下您正在尝试做些什么。他们有充分的理由警告。