C 定义之前是否允许使用typedef
最低代码:C 定义之前是否允许使用typedef,c,clang,iwyu,C,Clang,Iwyu,最低代码: //foo.h typedef struct foo_s foo_t; 结构foo\u s{ foo_t*next; }; iwyu坚持在我typedef将其转发到foo\u t之前,我先声明struct foo\u s 输出: $iwyu-cfoo.h foo.h应添加以下行: 结构foo_s; foo.h应删除以下行: foo.h的完整包含列表: 结构foo_s; --- 这在不同版本的iwyu中都是如此,包括添加了-Xiwyu--no_fwd_decls的较新版本 这是iw
//foo.h
typedef struct foo_s foo_t;
结构foo\u s{
foo_t*next;
};
iwyu
坚持在我typedef
将其转发到foo\u t
之前,我先声明struct foo\u s
输出:
$iwyu-cfoo.h
foo.h应添加以下行:
结构foo_s;
foo.h应删除以下行:
foo.h的完整包含列表:
结构foo_s;
---
这在不同版本的iwyu
中都是如此,包括添加了-Xiwyu--no_fwd_decls
的较新版本
这是iwyu
中的错误还是C
标准要求我在typedef
之前定义类型
C标准是否希望我在typedef
之前定义类型
事实并非如此。标准用语如下
6.7.2.3标签
表格的声明
struct-or-union identifier ;
struct-or-union identifier
指定结构或联合类型,并将标识符声明为
该类型的标记
如果是表单的类型说明符
struct-or-union identifier ;
struct-or-union identifier
除作为上述其中一种形式的一部分之外发生,并且没有其他形式
将标识符声明为标记是可见的,然后声明
结构或联合类型不完整,并将标识符声明为
该类型的标记
因此,您的原始声明对具有定义良好的行为。结构的声明在定义类型别名时隐式地添加到转换单元中,然后完成。工具不允许这样做的事实可能是由于错误、工具的限制,或者可能是试图强制执行特定的编码样式
有一点支持工具可能尝试实施的样式,这与C的范围概念有关。具体来说,函数参数列表范围。作为示例,请参考此简短示例
void bar(struct foo);
struct foo {
char c;
};
void bar(struct foo f) {}
碰巧的是,bar
的第一个声明是使用其参数列表唯一的类型声明的。struct foo
的初始声明与后面的函数定义中使用的类型不同。因此,守则
不会由合格的C编译器编译。在第一次函数声明之前在自己的行上声明结构可以解决此问题。这非常清楚地表明,您可以通过一个与您的代码非常类似的示例来“前向声明”一个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表单的类型说明符 如果没有枚举器,则列表只能在其类型之后出现 指定已完成 例如,这样一个typedef
typedef enum E AnotherE;
enum E { N };
此typedef时无效
enum E { N };
typedef enum E AnotherE;
这是有效的
对于结构,您可以在typedef定义中使用不完整的类型
8如果是表单的类型说明符
struct-or-union identifier ;
struct-or-union identifier
除作为上述其中一种形式的一部分之外发生,并且没有其他形式
将标识符声明为标记是可见的,然后声明
结构或联合类型不完整,并将标识符声明为
该类型的标记
在我看来像是
iwyu
bug。C标准允许这样做。但是如果你的工具不允许,那么你需要做工具允许的事情。