我有一个带回调函数的结构,回调函数需要一个指向结构的指针才能进行操作。如何正确定义这些元素,以便在没有警告的情况下进行编译?
typedef struct {
// some fields required for processing...
int (*doAction)(struct pr_PendingResponseItem *pr);
} pr_PendingResponseItem;
如果我删除pr参数的“struct”属性,我会收到错误。如果我把它留在里面,我会收到警告: “它的范围只是这个定义或声明,可能不是你想要的”
一切正常,但我想知道定义这种结构的正确方法。
同样相关的是定义一个自引用结构:
typedef struct LinkedItem_ {
LinkedItem_ * prev;
LinkedItem_ * next;
void * data;
} LinkedItem;
(我认为这是正确的,但如果与问题相关,则欢迎其他想法。)
答案 0 :(得分:12)
您的函数指针引用struct pr_PendingResponseItem,但您尚未声明struct pr_PendingResponseItem。你只有一个未命名的结构类型定义为名称pr_PendingResponseItem(并且该名称尚未建立)。
为结构命名:
struct pr_PendingResponseItem {
// some fields required for processing...
int (*doAction)(struct pr_PendingResponseItem *pr);
} ;
typedef struct pr_PendingResponseItem pr_PendingResponseItem;
答案 1 :(得分:8)
有两种方法可以实现 - 对于您的示例结构。它们基本上是同构的。
使用结构标记,如各种其他答案中所示。
typedef struct pr_PendingResponseItem
{
// some fields required for processing...
int (*doAction)(struct pr_PendingResponseItem *pr);
} pr_PendingResponseItem;
typedef struct LinkedItem
{
struct LinkedItem *prev;
struct LinkedItem *next;
void * data;
} LinkedItem;
使用typedef
为不完整的结构类型命名,并在结构定义中使用typedef
。
typedef struct pr_PendingResponseItem pr_PendingResponseItem;
struct pr_PendingResponseItem
{
// some fields required for processing...
int (*doAction)(pr_PendingResponseItem *pr);
};
typedef struct LinkedItem LinkedItem;
struct LinkedItem
{
LinkedItem *prev;
LinkedItem *next;
void * data;
};
请注意,结构标记与typedef
名称位于不同的名称空间中,因此不需要为typedef
和结构标记使用不同的名称。另请注意,在C ++中,typedef
是不必要的。
答案 2 :(得分:3)
类似这样的事情
typedef struct _pr_PendingResponseItem_ {
// some fields required for processing...
int (*doAction)(struct _pr_PendingResponseItem_ *pr);
} pr_PendingResponseItem;
应该修复它。
(经过测试和工作)
答案 3 :(得分:0)
添加上面的nos的答案。
这里的关键见解是,在处理类似“typedef struct name1 {} name2;”的声明时,您实际上声明了两种类型,即“ struct name1 {};”然后“typedef struct name1 name2 ;”,其中“ struct name1 ”是一种类型,您必须使用语法“struct name1”来引用它,并且“ name2 “是一种类型,您将其称为”name2“。您可以保留“name1”,在这种情况下,您只需定义第二种类型,第一种类型仍为匿名结构。
现在,在第一种情况下,如果要引用类型“struct pr_PendingResponseItem”,则需要声明该类型,而不是声明的匿名结构。因此,将结构声明更改为“struct pr_PendingResponseItem”。
在第二种情况下,您尝试将结构类型称为前向引用(即在其定义完成之前引用它),这是允许的,但是为了引用结构类型,所需的语法是“结构名称“。因此,您需要使用“struct LinkedItem _”替换定义中对“LinkedItem_”的前向引用。