在struct中引用struct会生成“incompatible-pointer-types”警告

时间:2017-04-04 07:56:01

标签: c pointers struct

编译并执行以下代码段:

#include <stdlib.h>
typedef struct {
    int count;
    struct lval **cell;
} lval;

lval *lval_new(void) {
    lval *v = malloc(sizeof(lval));
    v->cell = NULL;
    return v;
}

lval *lval_add(lval *x, lval *y) {
    x->count++;
    x->cell = realloc(x->cell, sizeof(lval *) * x->count);
    x->cell[x->count - 1] = y;
    return x;
}

int main() {
    lval *x = NULL;
    x = lval_new();
    x = lval_add(x, lval_new());
}

将在gcc下生成以下警告:

foo.c:16:31: warning: incompatible pointer types assigning to 'struct lval *' from 'lval *' [-Wincompatible-pointer-types]
        x->cell[x->count - 1] = y;

修改lval_add的代码并在(struct lval*)上添加y广告,如下所示:

lval *lval_add(lval *x, lval *y) {
    x->count++;
    x->cell = realloc(x->cell, sizeof(lval *) * x->count);
    x->cell[x->count - 1] = (struct lval *) y;
    return x;
}

修复此警告。

对我来说这感觉不自然(免责声明:我不是一个熟练的C程序员),我必须添加几个演员来修复我的程序中的这些警告。 是否有更好的方法来声明lval结构,以便它不会生成这些警告?

3 个答案:

答案 0 :(得分:2)

您的结构不会被称为struct lval

typedef struct lv {
  int count;
  struct lv **cell;
} lval;

因为结构应该是struct lvlval

答案 1 :(得分:2)

在此声明中

typedef struct {
    int count;
    struct lval **cell;
} lval;

宣布了两个不同的实体。第一个是指向不完整类型struct lval的双指针,第二个是带有别名lval的未命名结构。

这就是宣言的这一部分

typedef struct {

在声明的这一部分

时启动未命名结构的定义
    struct lval **cell;

又引入了一个不完整类型struct lval的声明。

因此struct lvallval表示不同的实体。

作为此转让声明的结果

x->cell[x->count - 1] = y;

左操作数的类型为struct lval *,而右操作数的类型为lval *,其中lval是未命名结构的别名。

我认为你的意思是

typedef struct lval {
        ^^^^^^^^^^^^
    int count;
    struct lval **cell;
} lval;

在这种情况下,名称lvalstruct lval类型的别名。

答案 2 :(得分:2)

在您的结构定义中,符号lval尚不存在。在结构已经定义之前它不存在。然后不是作为结构而是作为类型名称。

有两种解决问题的方法,都需要你命名结构。

第一个非常接近你已经在做的事情:

typedef struct lval {  // <- Note giving the structure a name
    int count;
    struct lval **cell;  // <- Using the structure name
} lval;

第二种是在定义结构之前定义类型别名:

typedef struct lval lval;  // Create type-name

struct lval {
    int count;
    lval **cell;  // <- Use the type-name
};

另请注意,您不初始化结构的count成员。这意味着它的值将是 indeterminate 并使用它可能会导致未定义的行为

lval_new函数中,您需要明确地将其设置为零。