[英]Is typedef allowed before definition
最低代碼:
// foo.h
typedef struct foo_s foo_t;
struct foo_s {
foo_t* next;
};
iwyu
堅持我在typedef
到 foo_t 之前轉發聲明struct foo_s
foo_t
。
Output:
$ iwyu -c foo.h
foo.h should add these lines:
struct foo_s;
foo.h should remove these lines:
The full include-list for foo.h:
struct foo_s;
---
這適用於不同版本的iwyu
,包括添加了-Xiwyu --no_fwd_decls
的較新版本。
這是iwyu
的錯誤還是C
標准要我在typedef
之前定義類型?
C 標准是否希望我在
typedef
之前定義類型?
它不是。 標准用語如下
6.7.2.3 標簽
7表格聲明
struct-or-union identifier;
指定結構或聯合類型並將標識符聲明為該類型的標記。
8如果一個類型說明符的形式
struct-or-union identifier
除了作為上述 forms 之一的一部分發生之外,並且沒有其他標識符聲明為標記可見,則它聲明一個不完整的結構或聯合類型,並將標識符聲明為該類型的標記。
因此,您的原始聲明對具有明確定義的行為。 結構的聲明在您定義類型別名時隱式添加到翻譯單元中,然后完成。 該工具不允許它的事實可能是由於錯誤,工具的限制,或者可能是試圖強制執行特定的編碼風格。
有一點支持該工具可能會嘗試強制執行的樣式,它與 scope 的 C 概念有關。 具體來說,function參數列表scope。 例如, 請參閱此問答並參考此簡短示例
void bar(struct foo);
struct foo {
char c;
};
void bar(struct foo f) {}
碰巧bar
的第一個聲明是使用其參數列表唯一的類型聲明的。 struct foo
的初始聲明與后面的 function 定義中使用的類型不同。 因此,代碼不會被符合標准的 C 編譯器編譯。 在第一個 function 聲明之前在自己的行上聲明結構可以解決此問題。
這個C11 Draft Standard通過與您的代碼非常相似的示例非常清楚地表明您可以“轉發聲明” typedef struct...
:
6.7.2.3 標簽
...
11 以下替代公式使用typedef機制:typedef struct tnode TNODE; struct tnode { int count; TNODE *left, *right; }; TNODE s, *sp;
這是一個錯誤。 似乎結構的 typedef 被認為與枚舉的 typedef 相同。
對於枚舉,您不能在 typedef 定義中使用不完整的類型
來自 C 標准(6.7.2.3 標簽)
3 形式的類型說明符
enum identifier
沒有枚舉器列表只能在它指定的類型完成后出現。
所以例如這樣一個typedef
typedef enum E AnotherE;
enum E { N };
此 typedef 時無效
enum E { N };
typedef enum E AnotherE;
已驗證。
對於結構,您可以在 typedef 定義中使用不完整的類型。
8 如果一個類型說明符的形式
struct-or-union identifier
除了作為上述 forms 之一的一部分發生之外,並且沒有其他標識符聲明為標記可見,則它聲明一個不完整的結構或聯合類型,並將標識符聲明為該類型的標記。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.