如何修复函数调用中指定参数的 'incompatible type'?

How to fix 'incompatible type' for specified parameter in function call?

我在 .h 中有以下 definitions/declarations:

    typedef enum NODETYPE {
        HEAD = -1,
        BODY = 0,
        TAIL = 1
    } NodeType;

    /*  node sruct  */
    typedef struct NODE {
        enum NODETYPE type;
        int len;
        struct NODE * next;
    } Node;  
    
    /*  create node  */
    static Node CreateNode(NodeType type, int len, Node child) {
        Node n = (Node){type, len};
        n.next = &child;

        return n;
    }

    #define CREATE_NODE(type, len, node)                CreateNode((type), (len), (node))

编译后(使用 Code::Blocks),我收到以下投诉:

285 | error: incompatible type for argument 3 of 'CreateNode'

第285行,具体来说就是#define子句。

我有什么问题吗?

我有以下内容进一步扩展了上面的 #define 子句:

    #define TLNODE()                                    CREATE_NODE(TAIL, -1, NULL)
    #define HDNODE()                                    CREATE_NODE(HEAD, -1, TLNODE())

在代码中我调用如下:

Node head = HDNODE();

更新
接受了一些评论和答案的建议。这是我所做的更改,问题已解决。

static Node* CreateNode(NodeType type, int len, struct NODE* child) {
    struct NODE* n = malloc(sizeof(struct NODE));

    n->type = type;
    n->len = len;
    n->next = child;

    return n;
}

#define CREATE_NODE(type, len, node)                (Node*)CreateNode((type), (len), (node))
#define TLNODE()                                    (Node*)CREATE_NODE(TAIL, -1, NULL)
#define HDNODE()                                    (Node*)CREATE_NODE(HEAD, -1, TLNODE())

TLNODE是错误的宏,但你的代码设计是一个更大的问题。

TLNODE不能将NULL传递给CreateNode的第3个参数,因为NULL通常定义为((void*)0),代表一个指针,而Node的类型由结构定义。

将指针的地址复制到 struct 类型的变量在 C 中是非法的。您需要为第三个参数使用相同的 Node 类型。

你最终可能会做这样的事情:

static const Node EMPTY_NODE = {};

并重新定义您的 TL_NODE 以使用它:

#define TLNODE() CREATE_NODE(TAIL, -1, EMPTY_NODE)

这可能有助于编译代码,但设计仍然存在缺陷。您正在创建的列表正在使用 CreateNode 的堆栈帧,因此 Node:next 指针将存储堆栈上的一个位置,该位置很快将被另一个函数重用。如果您使用该列表,您将破坏您自己的调用堆栈。

您需要更改 CreateNode 的设计以使用指向 Node 的指针并动态分配节点(使用 malloc)。

如果你真的想为此使用堆栈,请在你的 main 中分配一个大缓冲区(例如:char _storage[2048])并为你想要创建的节点创建一个分配器,在该 2KB 内space。不要直接引用调用堆栈。