警告:分配给' struct __bnode *'来自' const BinNode *' (又名' const struct __bnode *')丢弃限定符

时间:2018-05-31 17:16:43

标签: c

我正在研究二元搜索树,并定义了如下的结构。

typedef struct __bnode
{
    Member data;
    struct __bnode *left;
    struct __bnode *right;
} BinNode;

和我遇到问题的功能是

static void SetBinNode(BinNode *n, const Member *x, const BinNode *left, const BinNode *right)
{
    n->data = *x;
    n->left = left;
    n->right = right;
}

但我遇到了以下警告:

  

分配给' struct __bnode *'来自' const BinNode *' (又名' const   struct __bnode *')丢弃限定符

我认为警告并不危险,但这是因为我错过了一些东西。

我错过了什么?

1 个答案:

答案 0 :(得分:0)

您的代码会尝试将const BinNode *隐式转换为BinNode *,并放弃const。这是不安全的,所以你会收到警告。

以下是此代码如何咬你:

// Let's assume 'typedef int Member;' for simplicity

const BinNode zero = { 0, NULL, NULL };

int main(void) {
    BinNode node;
    SetBinNode(&node, NULL, &zero, NULL);
    node->left->data = 42;
    return 0;
}

此处我们有一个全局zero变量,即const

电话SetBinNode(&node, NULL, &zero, NULL);很好; &zero的类型为const BinNode *,这正是函数原型所说的SetBinNode

node->left->data = 42;编译也很好。 node->leftBinNode *; node->left->dataMember(即我们示例中的int)。

但这项任务可能会崩溃。致电node->left后,zero指向SetBinNode。因为zeroconst,编译器可能会将它放在只读内存中。现在,node->left->data的分配尝试修改const变量,从而触发分段错误。

所有这些都是在没有编译器投诉的情况下发生的......除了SetBinNode中的一行。

解决方案是将SetBinNode的类型更改为

static void SetBinNode(BinNode *n, const Member *x, BinNode *left, BinNode *right)

即。删除const。参数上的const正在做出无法保留的承诺。即使函数本身不通过*left*right进行写入,它仍然可以通过非const访问路径使对象可用,这可能会在以后引起麻烦。

相关问题