簡體   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