【问题标题】:How to handle circular dependencies in typedef'd structures如何处理 typedef 结构中的循环依赖关系
【发布时间】:2015-03-12 13:15:19
【问题描述】:

我有两个模块,a 和 b。

啊哈:

#ifndef A_H_
#define A_H_

#include "b.h"

typedef struct {
    b_t *b;
    ...
} a_t;

#endif // A_H_

b.h:

#ifndef B_H_
#define B_H_

#include "a.h"

typedef struct {
    a_t *a;
    ...
} b_t;

#endif // B_H_

如何更改它以使其能够编译? (我想保留两个独立的编译单元。)


编辑:我忘了让结构成员指针。

【问题讨论】:

  • 我首先想到的是指针的成员(仍然是有问题的设计,但至少可以通过前向声明并给至少一个结构一个标签)......这应该做什么?这两种结构都需要无限量的内存,出于同样的原因,您不能使用struct foo { struct foo f; };
  • 最后一点:不要使用_t 作为类型的后缀。以_t 结尾的标识符由POSIX 保留。

标签: c struct circular-dependency


【解决方案1】:

使用前向声明:

啊哈:

struct b_t;

typedef struct a_t {
  struct b_t *b;
} a_t;

b.h:

struct a_t;

typedef struct b_t {
  struct a_t *a;
} b_t;

【讨论】:

  • 谢谢,就是这样 - 我只需要通过直接使用结构名称来打破 typedef 的循环。
【解决方案2】:

[此答案仅适用于未将指针用作结构成员的原始问题]。

那是不可能的。自然不可能有这样的结构。

假设:

struct a {
    struct b b;
    int i;
};

struct b {
    struct a a;
    int i;
};

您对sizeof(struct a) 有什么期望?这个结构会爆炸,无法编译。

但是,如果你让它们变成指针,它可以被编译:

struct a;

struct b {
    struct a *ap;
};

struct a {
    struct b *bp;
};

这段代码确实可以编译:http://ideone.com/GKdUD9

【讨论】:

  • 在原始问题中,使用了指针。他在问关于 typedef 的循环依赖。
  • @ColeJohnson 一开始不是。这就是为什么所有答案都表明不可能的原因。
【解决方案3】:

这确实是不可能的。你不能让一个结构成为它自己的成员,甚至不能传递。但是,当您使用指针时,这是可能的。使用结构声明:

typedef struct a_struct *a_t;

typdef struct {
    a_t a;
} *b_t;

typedef struct a_struct {
    b_t b;
} a_t;

【讨论】:

    【解决方案4】:

    [此答案仅适用于原始问题,其中指针用作struct 成员]。

    你不能。

    基本上你有

    typedef struct {
        b_t b;
    } a_t;
    typedef struct {
        a_t a;
    } b_t;
    

    并且没有前向声明可以帮助您。你在这里有一个不可能的结构:sizeof 将是无限的。

    【讨论】:

    • 这个“你不能”只适用于相互包含是直接的情况;当你有指针时这是可能的。
    • 在原始问题中,使用了指针。这不是问题。
    • 问题已被编辑:现在几乎所有的答案都已失效。
    猜你喜欢
    • 2020-11-11
    • 2013-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多