[英]Why can you create typedefs to a struct that doesn't exist?
以下代碼編譯良好。
header.h:
typedef struct Placeholder_Type* Placeholder;
實現.cpp:
#include "header.h"
void doSomething(Placeholder t) {
(void) t;
}
int main() {
int *a = new int();
doSomething((Placeholder)a);
}
編譯命令:
clang++ impl.cpp
Placeholder_Type 類型在任何地方都不存在,並且在 output 二進制文件中不作為符號存在。
為什么為不存在的類型創建 typedef 是合法的?
為什么我可以使用不存在的類型創建 function?
這是否等同於僅使用 void* 但命名為“占位符”?
struct Placeholder_Type
聲明 struct Placeholder_Type
(但沒有定義它),無論它出現在哪里。 即使它在typedef
中。 因此,您不會為不存在的結構創建 typedef,而是為您剛剛聲明的結構創建 typedef(如果編譯器還不知道它,則創建它)。
至於為什么,因為這樣可以讓結構的定義遠離公共接口。 例如,這是在 C 中實現不透明 object 的典型方法:
// mytype.h
typedef struct MytypeImpl* Mytype;
Mytype create_mytype();
void destroy_mytype(Mytype o);
void do_something_with_mytype(Mytype o, int i);
// mytype.c
struct MytypeImpl {
int something;
int otherthing;
};
Mytype create_mytype() {
Mytype o = malloc(sizeof(*o));
o->something = 0;
o->otherthing = 0;
return o;
}
void destroy_mytype(Mytype o) {
free(o);
}
// etc.
當然,個別 styles 可能在細節上有所不同。 但關鍵是結構的定義在 mytype.c 之外是不可見的,所以沒有人可以訪問數據成員。
為什么不? 據我所知,“存在”不是一個官方術語。 類型可以聲明但不定義,也可以聲明和定義。 在第一種情況下,類型被認為是不完整的。 對於不完整的類型,您無能為力。 例如,您不能創建該類型的對象。 但是,您可以使用指向不完整類型的指針。 編譯器需要知道的只是類型的聲明。 進一步注意 typedef 確實包含Placeholder_Type
的聲明:
typedef struct Placeholder_Type* Placeholder;
^---------------------^ declares the class named Placeholder_Type
在您的代碼中,您永遠不會創建 object 或使用它編譯的Placeholder_Type
成員。 我不是 100% 確定,但我認為也沒有 UB。 強制轉換int
看起來不太好,但是由於您從未真正取消引用指針,因此沒有任何問題。
有關更多信息,請參閱有關前向聲明的非常相關的問題: C++ 中的前向聲明是什么? 我什么時候可以使用前向聲明?
並非所有聲明都是同時定義。
例如,您可以聲明尚未定義的 function
void func( void );
然后引用名稱func
。
或者您可以聲明一個 class 例如
class A
{
friend class B;
//...
};
聲明在給定的 scope 中引入名稱。
只有在評估上下文中使用名稱時,它必須被定義並具有完整的類型。
在這份聲明中
typedef struct Placeholder_Type* Placeholder;
引入了兩個名稱: Placeholder_Type
和Placeholder
。 Placeholder 是指針類型struct Placeholder_Type*
的別名。 指針類型的對象總是完整的對象。 您可以使用表達式計算其大小
sizeof( Placeholder )
這與擁有指向類型void
的指針相同。
void *p;
void 類型始終是不完整類型,因為指針類型本身就是完整類型。 如果您不嘗試取消引用指針或應用指針算術,則引用類型不需要是完整的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.