简体   繁体   English

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

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

For the sake of simplicity I'm going to recreate the actual situation with dummy structures.为简单起见,我将使用虚拟结构重新创建实际情况。 I have this structure (not my code, I can't edit it):我有这个结构(不是我的代码,我无法编辑它):

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

Then in one of my headers I extended it this way:然后在我的一个标题中,我以这种方式扩展了它:

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

Now, in my function, I have:现在,在我的函数中,我有:

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;

This last line of code makes the compiler throw this error:最后一行代码使编译器抛出此错误:

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

Where is the error?错误在哪里? EDIT: the piece of code that triggers the compiler has header_a.h and my_header.h included.编辑:触发编译器的代码my_header.h包含header_a.hmy_header.h private_header_a.h cannot be included directly as not installed (I should copy-paste it, but frankly I would like to avoid to do that) private_header_a.h不能直接包含,因为没有安装(我应该复制粘贴它,但坦率地说,我想避免这样做)

Here's two fundamental rules:这里有两个基本规则:

  1. Each c file is compiled separately每个c文件单独编译
  2. When you #include a file, think of it as directly replacing the #include line with the contents of the file being included.当你 #include 一个文件时,把它想象成直接用被包含的文件的内容替换 #include 行。

Therefore, you are compiling a piece of source code that looks like this:因此,您正在编译一段如下所示的源代码:

struct A_s {
 int a1;
};

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

void foo() {
  B_t* b;
}

This code doesn't know what A_t is.这段代码不知道A_t是什么。 You've never defined that in the code that's visible to the compiler.您从未在编译器可见的代码中定义它。

A trivial way to fix this is to replace A_t with struct A_s .解决此问题的一个简单方法是将A_t替换为struct A_s

The compiler error is probably intentional - the library's designers don't want you using A_t directly in that sort of way.编译器错误可能是故意的 - 库的设计者不希望您以这种方式直接使用A_t

When a struct is only declared in a library's public header file, and only defined in the library's private implementation files, that means you're not supposed to know or care about its members or even size.当一个结构只在库的公共头文件中声明,并且只在库的私有实现文件中定义时,这意味着你不应该知道或关心它的成员,甚至大小。 So looking up that the struct has a member named a1 and writing b->af->a1 is not the intended use.因此查找该结构体有一个名为a1的成员并编写b->af->a1不是预期用途。 This arrangement is called an "opaque handle".这种布置称为“不透明手柄”。 A few of its benefits are that the library keeps your application code from initializing or changing members in ways that don't make sense, and a future version of the library can change the names, numbers, and meanings of the members without breaking your application code.它的一些好处是该库可以防止您的应用程序代码以没有意义的方式初始化或更改成员,并且该库的未来版本可以更改成员的名称、数字和含义,而不会破坏您的应用程序代码。

(Also, how did you get a valid pointer for b->af without doing malloc(sizeof(A_t)) or similar? That sizeof would also cause a compiler error about the incomplete struct type.) (此外,您如何在不执行malloc(sizeof(A_t))或类似操作的情况下获得b->af的有效指针? sizeof还会导致编译器关于不完整结构类型的错误。)

When a library uses an opaque handle, since you can't create any such objects yourself, it will typically provide functions that create the objects for you.当库使用不透明句柄时,由于您无法自己创建任何此类对象,因此它通常会提供为您创建对象的函数。 Look for public functions in the library with names including init , create , open , etc. which return an A_t* pointer, and read their documentation.在库中查找名称包括initcreateopen等的公共函数,这些函数返回A_t*指针,并阅读它们的文档。 Usually there will also be a corresponding destroy , cleanup , close , etc. function which the program should call later when the library object is no longer needed.通常还会有相应的destroycleanupclose等函数,当不再需要库对象时,程序应该稍后调用这些函数。 (In the case of some very simple handles, the function which creates the object might say instead you should just pass the pointer to free . But only do this if the documentation says to!) (在一些非常简单的句柄的情况下,创建对象的函数可能会说你应该将指针传递给free 。但只有在文档说的时候才这样做!)

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

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