C中的前向结构声明;不工作

时间:2014-07-08 00:45:46

标签: c struct header-files forward-declaration

我阅读了所有其他帖子但尚未成功(例如forward declaration of a struct in C?

有两个头文件,其中的函数引用了彼此的结构。头。 前瞻性声明不起作用......当然因为我还在做错了:)想法?

foo.h中:

typedef struct{
...
}foostruct;
extern foostruct fooStruct; //this struct used in foo.c and other c files
typedef struct barstruct; //attempt at forward declaration
void fooFctn(barstruct *barVar); //needs definition from bar.h

bar.h:

typedef struct{
...
}barstruct;
extern barstruct barStruct; //this struct used in bar.c and other c files
typedef struct foostruct; //attempt at forward declaration
void fooFctn(foostruct *fooVar); //needs definition from foo.h

错误是

error: useless storage class specifier in empty declaration [-Werror]
src/search.h:123:18: error: unknown type name 'foostruct'

由于这些结构是typedef-d,我最初也尝试过" foostruct;"没有(当然)不起作用的标识符,同样声明" typedef struct fooVar foostruct"生成重新定义错误。

3 个答案:

答案 0 :(得分:4)

foo.h中,此代码:

typedef struct barstruct;

是一个简并typedef,它宣告struct barstruct存在,但没有为它提供替代名称(因此“空声明中的无用存储类说明符”警告/错误)。你需要:

typedef struct barstruct barstruct;

然后代码将在foo.h中正常运行。 bar.h struct foostruct需要进行相应的更改。

但是,这仍然会让您遇到问题。 barstruct中声明的类型foo.hbarstruct中声明的类型bar.h不同(因为一个是标记结构,一个是无标记结构)。有几种方法可以解决这个问题。在C11(但不是C99或C89)中,如果它们相同,您可以重复typedef

因此,您将拥有两条typedef行:

typedef struct barstruct barstruct;
typedef struct foostruct foostruct;

位于标题的顶部,然后在bar.h中定义:

struct barstruct { … };

foo.h

struct foostruct { … };

如果与早期版本的C的兼容性很重要,那么您需要考虑在函数声明中使用struct barstructstruct foostruct

foo.h

typedef struct foostruct foostruct;

struct foostruct
{
   …
};

extern foostruct fooStruct;
struct barstruct;
void fooFctn(struct barstruct *barVar);

类似于bar.h。当然,这也适用于C11。

答案 1 :(得分:2)

正确地键入你的结构应解决你的问题。

typedef struct foostruct foostruct;

答案 2 :(得分:1)

结构和标签

struct { ... };是一个匿名结构。它仅对typedef有用,并且仅当在该文件中使用和声明该typedef名称时才有用。换句话说,它不能与前向声明一起使用。

但是,struct X { ... };struct X类型的结构。它可以用于前向声明。请注意,X只是用于表示特定结构类型的标记名称,而不是实际类型。标记名称用于区分其他声明的结构类型。这有时让人困惑,所以一个例子可能有所帮助。请注意,所有声明的结构类型都不同:

/* Declare an anonymous structure. */
struct {
    int n;
};

/* Another anonymous structure. It in different from the previous one. */
struct {
    double d;
};

/* Declare a structure of type `struct bar'. */
struct bar {
    int n;
};

/* Declare a structure of type `struct foo'. */
struct foo {
    int n;
};


/* Declare a variable `var' of type `struct foo'. */
struct foo var;

/* Unless a typedef for the `foo' type exists, or a preprocessor macro is used to replace `foo' with an actual type, this is a compilation error. */
foo var2;

请注意,如果您尝试声明具有相同标记名称的两个结构,则会出错。

<强>的typedef

typedef的表单与没有初始值设定项的变量声明相同:

typedef TYPE NAME;

例如:

typedef int Integer;

声明Integer类型与int相同。结构可以做同样的事情:

/* Typedef'd anonymous structure */
typedef struct {
    int foo;
} fooBType;

/* Typedef'd `struct foostruct' structure */
typedef struct foostruct {
    int foo;
} fooGType;

两者之间的区别:

  • fooBType在其他文件中引用的结构类型的前向声明是不可能的,因为fooBType引用的结构是匿名的
  • struct foostruct引用的结构类型fooGType的前向声明是可能的,因为结构标记和struct关键字可以引用类型,如struct foostruct }或typedef struct foostruct fooGType;

我希望这会有所帮助。