6.2.5
在翻译单元内的各个点处,对象类型可以是 不完整(缺乏足够的信息来确定。的大小 那种类型的对象。)
另外
6.2.5 19)void类型包含一组空值;它是一个不完整的对象类型,无法完成。
和
6.5.3.4 sizeof运算符不应用于具有函数类型或不完整类型的表达式,
但Visual Studio 2010为
打印0
printf("Size of void is %d\n",sizeof(void));
我的问题是'什么是incomplete types
'?
struct temp
{
int i;
char ch;
int j;
};
此处temp
不完整吗?如果是,为什么它不完整(我们知道临时的大小)?没有清楚地了解incomplete types
。解释此问题的任何代码段都会有所帮助。
答案 0 :(得分:8)
您的struct temp
不完整直到发生右括号的位置:
struct temp
{
int i;
char ch;
int j;
};// <-- here
结构在temp
符号后面声明(存在),但在实际定义完成之前它是不完整的。这就是为什么你可以拥有这样的东西:
struct temp
{
int i;
char ch;
struct temp *next; // can use pointers to incomplete types.
};
没有语法错误。
C区分声明(声明某些东西存在)和定义(实际定义它是什么)。
另一个不完整的类型(声明但尚未定义)是:
struct temp;
这种情况通常用于提供类型存在的opaque types in C(因此您可以声明指向它的指针)但未定义(因此您无法弄清楚其中的内容)。定义通常仅限于实现它的代码,而客户端使用的标头只有不完整的声明。
答案 1 :(得分:2)
不,你的struct temp
例子肯定是完整的;假设int
是4个字节,char
是1,我可以很容易地计算该结构中的9个字节(忽略填充)。
不完整类型的另一个例子是:
struct this_is_incomplete;
这告诉编译器,“嘿,这个结构存在,但你还不知道它里面有什么”。这对于信息隐藏非常有用,但是当您需要将指针传递给类型时:
int some_function(struct this_is_incomplete* ptr);
编译器可以正确地生成对此函数的调用,因为它知道指针是4(或8)个字节,即使它不知道指针指向的东西有多大。
答案 2 :(得分:1)
当声明其名称而不是其定义时,类型可能不完整。当您在头文件中转发声明类型时会发生这种情况。
说,record.h包含:
struct record_t;
void process_record(struct record_t *r);
而record.c包含:
struct record_t {
int data;
};
如果在另一个模块中说“usage.c”,则执行此操作:
#include "record.h"
const int rec_size = sizeof(struct record_t); // FAIL
“usage.c”编译单元中的类型record_t
不完整,因为它只知道名称record_t
,而不知道该类型是由什么组成的。