【问题标题】:Referencing struct within a struct generates "incompatible-pointer-types" warnings在结构中引用结构会生成“不兼容的指针类型”警告
【发布时间】:2017-04-04 07:56:01
【问题描述】:

编译并执行以下sn-p:

#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的代码并在y上添加(struct lval*)转换如下:

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 结构,这样它就不会产生这些警告?

【问题讨论】:

  • 你确定这是代码吗?我认为您的结构声明有问题,或者您正在省略代码。
  • struct lvallval 是不同的类型
  • @M.M 我们在这里看不到任何struct lval,对吗? :)
  • @SouravGhosh 我们看到 1 或 2

标签: c pointers struct


【解决方案1】:

在您的结构定义中,符号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 成员。这意味着它的值将是不确定的,使用它可能会导致未定义的行为

在您的 lval_new 函数中,您需要将其显式设置为零。

【讨论】:

  • 感谢您的回答。该代码只是我正在做的事情的摘录(为了准备)。所以是的,它相当不完整,count 在完整的代码中被正确初始化。
  • @ohe 如果您不希望我们回答错误的问题、做出错误的猜测或记下错误的细节,那么创建Minimal, Complete, and Verifiable Example 并向我们展示这一点很重要。
  • 好吧。我的问题涉及编译器对结构提出的警告。在这种情况下,给定的代码是最小的、完整的和可验证的。你没有回答错误的问题。你正在回答一个没有被问到的问题。对于我提出的问题,到目前为止,您的回答是最好的。谢谢你。
【解决方案2】:

你的结构没有被称为struct lval

试试

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

因为结构应该是struct lvlval

【讨论】:

    【解决方案3】:

    在此声明中

    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;
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多