4

在下面的:

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 *就足够了,不是吗?(因为我无法更改指针以影响调用者)

感谢您花时间阅读。

4

3 回答 3

7

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

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

绝不能做你正在做的事。

于 2011-02-10T23:43:24.977 回答
6

如果您不想A通过其指针 from进行修改adt,那么您也应该将该指针设为 const,即:

struct adt {
    const void * A;
};

这将使错误消失。

如果您确实A通过进行修改adtnew_adt则应采用非常量指针。


编辑:更一般的注释,可能会有所帮助:

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

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

于 2011-02-10T23:43:03.733 回答
2

你可以把 c​​onst 扔掉:

r->A = (void *) A;

但是,问题不在于如何避免警告,而在于您要尝试做什么。编译器警告您,因为您告诉编译器“A”不可写,但您试图将其存储在将其定义为可写的位置。从语义上讲,这通常不好。

想象一下,“A”指向您的二进制数据部分中的一个位置;在丢弃 const 之后尝试写入它,很可能会导致段错误。

因此,实际上,在尝试解决编译器警告之前,请仔细考虑您要尝试做什么。他们是有充分理由的警告。

于 2011-02-10T23:43:20.203 回答