繁体   English   中英

C 嵌套结构的问题。 错误:无效使用不完整的 typedef

[英]Problem with C nested structure. error: invalid use of incomplete typedef

为简单起见,我将使用虚拟结构重新创建实际情况。 我有这个结构(不是我的代码,我无法编辑它):

// private_header_a.h
struct A_s{
 int a1;
};
// header_a.h
typedef struct A_s A_t;

然后在我的一个标题中,我以这种方式扩展了它:

// my_header.h
typedef struct B_s{
 A_t* a_f;
 int b1;
} B_t;

现在,在我的函数中,我有:

B_t* b;
// Initialization and some other code
b->b1 = 4; // Just an example and compiler does not give any error
// Some other code
b->a_f->a1;

最后一行代码使编译器抛出此错误:

error: invalid use of incomplete typedef ‘A_t’ {aka ‘struct A_s’}

错误在哪里? 编辑:触发编译器的代码my_header.h包含header_a.hmy_header.h private_header_a.h不能直接包含,因为没有安装(我应该复制粘贴它,但坦率地说,我想避免这样做)

这里有两个基本规则:

  1. 每个c文件单独编译
  2. 当你 #include 一个文件时,把它想象成直接用被包含的文件的内容替换 #include 行。

因此,您正在编译一段如下所示的源代码:

struct A_s {
 int a1;
};

typedef struct B_s {
 A_t* a_f;
 int b1;
} B_t;

void foo() {
  B_t* b;
}

这段代码不知道A_t是什么。 您从未在编译器可见的代码中定义它。

解决此问题的一个简单方法是将A_t替换为struct A_s

编译器错误可能是故意的 - 库的设计者不希望您以这种方式直接使用A_t

当一个结构只在库的公共头文件中声明,并且只在库的私有实现文件中定义时,这意味着你不应该知道或关心它的成员,甚至大小。 因此查找该结构体有一个名为a1的成员并编写b->af->a1不是预期用途。 这种布置称为“不透明手柄”。 它的一些好处是该库可以防止您的应用程序代码以没有意义的方式初始化或更改成员,并且该库的未来版本可以更改成员的名称、数字和含义,而不会破坏您的应用程序代码。

(此外,您如何在不执行malloc(sizeof(A_t))或类似操作的情况下获得b->af的有效指针? sizeof还会导致编译器关于不完整结构类型的错误。)

当库使用不透明句柄时,由于您无法自己创建任何此类对象,因此它通常会提供为您创建对象的函数。 在库中查找名称包括initcreateopen等的公共函数,这些函数返回A_t*指针,并阅读它们的文档。 通常还会有相应的destroycleanupclose等函数,当不再需要库对象时,程序应该稍后调用这些函数。 (在一些非常简单的句柄的情况下,创建对象的函数可能会说你应该将指针传递给free 。但只有在文档说的时候才这样做!)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM