如何声明一个不会生成警告的结构?

时间:2012-02-25 09:42:33

标签: c struct

这个问题似乎是一个经典问题,但我找不到答案:

我有两个用C语言编写的结构类型------结构类型A和结构类型B,B使用A而A同时使用B.

在a.h中:

#include "b.h"
struct B;
typedef struct A {
    void (*func)(struct B* b);
}A;

在b.h中:

#include "a.h"
typedef struct B {
    A a;
}B;

虽然这会起作用,但它有一个结果---当使用函数fun“func”时,如果我传递一个在表单中声明的​​变量:

B* someb;

struct B* someb;

编译时会出现警告,说不兼容的指针类型。这是正常的吗?我可以避免这个警告吗?

4 个答案:

答案 0 :(得分:2)

a.h标题文件中,只需删除第#include "b.h"行即可。您只需要前瞻性声明struct B;

该更改将修复循环包含依赖项,并使使用这些标题的任何代码更加清晰。

然后,只要您想要使用B结构,只需添加b.h,并使用或不使用struct关键字。

一些代码用于说明:a.h头文件:

/* a.h */
struct B;

typedef struct A {
    void (*func)(struct B* b);
} A;

b.h头文件:

/* b.h */
#include "a.h"

typedef struct B {
    A a;
} B;

使用这些头文件的文件:

/* some_file.c */
#include "b.h"

void fun() {
    B someb;
    someb.a.func(&someb);
}

void fun2() {
    struct B someb;
    someb.a.func(&someb);
}

funfun2都很好(从编译器的角度来看 - func尚未初始化,因此调用它会在运行时导致问题。)< / p>

答案 1 :(得分:2)

循环包含依赖项永远不是一个好主意。

最简单的方法是在“a.h”中为struct标记 typedef提供前向声明

typedef struct A A;
typedef struct B B;

答案 2 :(得分:0)

函数func,因为你声明它获取了一个指向struct B对象的指针,所以在调用函数时你应该这样做:

B* somePointer; //because of your typedef you can omit struct 
func(somePointer);

我省略了你应该管理的内存分配部分......

正如问题Compiler Warning: Initialization incompatible pointer type所示,您应该传递一个指向该函数的指针,以便在对象中显示更改,否则您只是传递一个struct B的副本,并且您所做的每个更改都将仅在功能范围。

我认为这是警告的原因。

答案 3 :(得分:0)

struct whatever { /* ... */ };定义了一种新类型 新类型名称为 struct whatever

您可以在定义类型的同一语句中使用typedef为类型定义另一个名称

typedef struct whatever { /* ... */ } newtypename;

或以不同的陈述

struct whatever { /* ... */ };
typedef struct whatever newtypename;

您甚至可以定义没有名称的struct类型并为其获取新名称

typedef struct { /* ... */ } newtypenameforstructwithnotag;