4

6.2.5

在翻译单元内的不同点,对象类型可能不完整(缺乏足够的信息来确定该类型对象的大小)。

6.2.5 19) void 类型包含一组空值;它是无法完成的不完整对象类型。

6.5.3.4 sizeof 运算符不得应用于具有函数类型或不完整类型的表达式,

但是 Visual Studio 20100打印

printf("Size of void is %d\n",sizeof(void));

我的问题是'什么是incomplete types'?

struct temp
{
    int i;
    char ch;
    int j;
};

temp这里不完整吗?如果是,为什么它不完整(我们知道 temp 的大小)?没有清楚的想法incomplete types。任何解释这一点的代码片段都会有所帮助。

4

3 回答 3

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;

这种情况通常用于在 C 中提供不透明类型,其中类型存在(因此您可以声明指向它的指针)但未定义(因此您无法弄清楚其中有什么)。定义通常仅限于实现它的代码,而客户端使用的标头只有不完整的声明。

于 2013-09-11T06:15:40.813 回答
2

不,您的struct temp示例肯定是完整的;假设int是 4 个字节,并且char是 1,我可以轻松地计算该结构中的 9 个字节(忽略填充)。

不完整类型的另一个示例是:

struct this_is_incomplete;

这告诉编译器,“嘿,这个结构存在,但你还不知道里面有什么”。这对于信息隐藏很有用,但是当您需要传递指向类型的指针时:

int some_function(struct this_is_incomplete* ptr);

编译器可以正确生成对该函数的调用,因为它知道指针是 4(或 8)字节,即使它不知道指针指向的东西有多大。

于 2013-09-11T06:09:16.057 回答
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,而不知道类型是由什么组成的。

于 2013-09-11T06:16:39.977 回答