【问题标题】:Assignment of const to non-const in C在 C 中将 const 分配给非 const
【发布时间】:2011-06-25 05:45:57
【问题描述】:

如下:

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

感谢您抽出宝贵时间阅读。

【问题讨论】:

  • 你在哪里声明r?它的类型是什么?

标签: c constants void-pointers


【解决方案1】:

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

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

不得做你正在做的事。

【讨论】:

    【解决方案2】:

    如果您不想通过来自adt 的指针来修改A,那么您也应该将那个 指针设为const,即:

    struct adt {
        const void * A;
    };
    

    这将使错误消失。

    如果您确实想修改Aadt,那么new_adt 应该采用非常量指针。


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

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

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

    【讨论】:

    • 谢谢,但请确保我理解:我想在将来替换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_A
    【解决方案3】:

    你可以把 c​​onst 扔掉:

    r->A = (void *) A;
    

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-15
      • 1970-01-01
      • 2011-01-31
      • 2011-08-16
      • 2020-11-04
      • 2023-04-02
      • 1970-01-01
      • 2013-12-11
      相关资源
      最近更新 更多