最低限度代码:
// foo.h
typedef struct foo_s foo_t;
struct foo_s {
foo_t* next;
};iwyu坚持在将struct foo_s声明给foo_t之前将其转发给foo_t。
输出:
$ 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之前定义类型?
发布于 2020-05-06 21:56:55
C标准要求我在
typedef之前定义类型吗?
事实并非如此。标准语句如下
6.7.2.3标记 7表单的声明 结构或联合标识符; 指定结构或联合类型,并将标识符声明为该类型的标记。 如果窗体的类型说明符为8,则为 结构或联合标识符 不作为上述表单的一部分发生,并且标识符作为标记的其他声明不可见,则声明不完整的结构或联合类型,并声明标识符为该类型的标记。
因此,原始的对声明具有定义良好的行为。结构的声明在定义类型别名时隐式地添加到翻译单元中,然后在之后完成。该工具不允许使用它的原因可能是错误、工具的限制,或者是执行特定编码风格的尝试。
有一点支持该工具可能尝试执行的样式,它与C概念的作用域有关。具体来说,函数参数列表作用域。作为一个例子,见这个问答并参考这个简短的例子
void bar(struct foo);
struct foo {
char c;
};
void bar(struct foo f) {}碰巧的是,bar的第一个声明是用其参数列表特有的类型声明的。struct foo的初始声明与后面函数定义中使用的声明类型不同。因此,代码将不会由符合标准的C编译器编译。在第一个函数声明之前在自己的行上声明结构可以解决这个问题。
发布于 2020-05-06 22:02:36
这个C11标准草案非常清楚地表明,您可以通过一个非常类似于您的代码的示例“转发”一个typedef struct...:
6.7.2.3标记 ..。 11 .以下备选配方使用了typedef机制: 结构TNODE;struct tnode { int计数;tnode *左*右;};TNODE s,*sp;
发布于 2020-05-06 22:05:36
是个虫子。看起来,用于结构的typedef与枚举的typedef是一样的。
对于枚举,您可能不会在ty胡枝子定义中使用不完整的类型。
来自C标准(6.7.2.3标记)
3.表格的类型说明符
enum identifier 如果没有枚举数列表,则只有在它指定的类型完成后才会出现。
所以,例如,这样一个类型的
typedef enum E AnotherE;
enum E { N };在此类型胡枝子f无效时
enum E { N };
typedef enum E AnotherE;是有效的。
对于结构,您可以使用类型不完整的类型来定义类型。
8如果窗体的类型说明符
struct-or-union identifier不作为上述表单的一部分发生,并且标识符作为标记的其他声明不可见,则声明不完整的结构或联合类型,并声明标识符为该类型的标记。
https://stackoverflow.com/questions/61645966
复制相似问题