如何修复函数调用中指定参数的 '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。不要直接引用调用堆栈。
我在 .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。不要直接引用调用堆栈。