c - 如果 struct 类型在另一个 .c 文件中定义,它会变成不完整类型吗?
问题描述
我对这段代码没有任何问题:
#include <stdio.h>
struct foo
{
void * data;
};
int main()
{
printf("%ul\n", sizeof(struct foo));
}
但是一旦结构在另一个文件中声明并提供给编译器,结构就会神奇地变成不完整的类型:
编辑(我没有提供所有代码):
: _
struct foo
公元前:
#include "b.h"
struct foo
{
void * data;
};
交流:
#include <stdio.h>
#include "b.h"
int main()
{
printf("%lu\n",sizeof(struct foo));
}
触发:
$gcc a.c b.c
仍然是同样的错误:
error: invalid application of ‘sizeof’ to incomplete type ‘struct foo’
printf("%lu\n",sizeof(struct foo));
解决方案
一个翻译单元,即一个 .c
文件及其#include
d.h
文件必须是独立的,按要求的顺序包含编译翻译单元所需的所有定义和声明。即使您.c
在 GCC 命令行上提供了多个文件,这些文件中的每一个都被视为一个单独的翻译单元。
顺序意味着翻译单元的 C 源代码可以一次性编译,这意味着编译器可以在解析程序的同时生成机器代码,而不必在内存中保留超过绝对必要的内容,因此所有必要的声明和定义必须在需要之前出现在源代码中。
C11/C18 标准说( 6.5.3.4p1)
sizeof 运算符不应应用于具有函数类型或不完整类型的表达式[...]
- 具有相同范围并使用相同标记的结构、联合或枚举类型的所有声明都声明相同的类型。无论在同一翻译单元中是否有标记或该类型的其他声明,类型都是不完整的*[129]*,直到紧接在定义内容的列表的右大括号之后,然后才完成。
脚注129指出
[129]不完整类型只能在不需要该类型对象的大小时使用。例如,当
typedef
名称被声明为结构或联合的说明符时,或者当声明指向或返回结构或联合的函数时,不需要它。(参见 6.2.5 中的不完整类型。)在调用或定义这样的函数之前,规范必须是完整的。
即您的翻译单元a.c
由以下代码组成:
// code included from <stdio.h>
...
// code included from "b.h"
struct foo;
// rest of code in a.c
int main()
{
printf("%lu\n",sizeof(struct foo));
}
这是C编译器所拥有的所有知识,struct foo
当它到达 6.7.2.3p4sizeof(struct foo)
时,类型仍然不完整并产生错误。struct foo
作为修复,b.h
应该,而不是完全无用和无操作struct foo;
具有实际的结构定义:
b.h
:
struct foo
{
void * data;
};
推荐阅读
- python - 让我的基于海龟的游戏退出按钮工作
- javascript - 用javascript控制TAB的顺序(反应)
- cookies - 通过 nuxt js 设置 cookie 时花括号转换为字符转义码
- c++ - 将数据结构作为类函数传递
- clojure - ring-swagger 中查询参数说明
- ruby-on-rails - Rails 解析请求,因此我将所有查询参数作为一个参数
- python - 在 python 中拟合剂量反应模型(R drc 库等效)
- kubernetes - how to forward request to public service like cdn using istio virtualservice?
- react-native - 我应该如何在 react-native 中使用 backBehaviour react-drawer-navigator 配置?
- javascript - 修改状态后组件未正确重新渲染