[英]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.