以下内容:
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 *
就足够了,不是吗? (因为我无法更改指针以使其影响调用者)
感谢您花时间阅读。
答案 0 :(得分:7)
通过使用const void * const,我假装没有对输入进行任何更改。
您 假装 表示不会对输入进行任何更改,您已明确告诉编译器您已< strong> 保证 不会对输入进行任何更改。
你 做你正在做的事情。
答案 1 :(得分:5)
如果你永远不想通过A
的指针修改adt
,那么你也应该那个指针const,即:
struct adt {
const void * A;
};
这将使错误消失。
如果你做想要通过A
修改adt
,那么new_adt
应该采用非常量指针。
编辑:更一般的说明,这可能会有所帮助:
const
关键字通常适用于 left 的类型。但是,如果左侧没有类型,则它将应用于右侧的类型。所以:
const int * A
与int const * A
相同(const
适用于int
,而不适用于指针),但在int * const A
中,const适用于指针,而不是int。
维基百科有一个更全面的解释:const-correctness。该页面的“指针和引用”部分包含一个示例,其中包含可应用于指针的const和非const的各种组合。
答案 2 :(得分:0)
你可以抛弃const:
r->A = (void *) A;
但问题不在于如何避免警告,更多的是关于你想要做什么。编译器警告你,因为你告诉编译器“A”不可写,但你试图将它存储在一个定义为可写的位置。从语义上讲,这通常不行。
想象一下,“A”指向二进制数据部分中的某个位置;尝试写入它后,将const转换掉,最有可能导致段错误。
所以,实际上,在尝试解决编译器警告之前,请考虑一下您正在尝试做些什么。他们有充分的理由警告。