【问题标题】:Incomplete types in CC中的不完整类型
【发布时间】:2013-09-15 00:59:07
【问题描述】:

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 在这里不完整吗?如果是,为什么它不完整(我们知道 temp 的大小)?不清楚incomplete types。任何解释这一点的代码 sn-p 都会有所帮助。

【问题讨论】:

  • 因为 Visual Studio 使用 VC++。尝试使用 g++ 进行相同的编译。您将收到这样的警告:“main.cpp:7:36: 警告:'sizeof' 无效应用到 void 类型 [-Wpointer-arith]”
  • 您的struct temp 不是不完整的类型。这是不完整的类型:struct temp;
  • 除 c++ 标签本身之外的所有内容(标题、标准摘录、代码使用)都表明这是一个 C 问题,所以我删除了 C++ 标签。

标签: c visual-studio-2010 types


【解决方案1】:

您的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(因此您可以声明指向它的指针)但未定义(因此您无法弄清楚其中的内容)。定义通常仅限于实现它的代码,而客户端使用的标头只有不完整的声明。

【讨论】:

  • 我感觉在做什么typedef struct temp { int i; char ch;int j;}Temp; 我可以得到尺寸,但是提到sizeof(temp) 我无法得到尺寸。这意味着,temp 不是一个完整的类型。是这样吗?
  • @Patil,在 C 语言中,您将使用 sizeof(struct temp)。 C++ 允许您删除struct,C 不允许。 struct temp 和 Temp 都是 typedef 之后的完整类型。
  • 在哪里可以找到所有这些信息?没有教科书这样解释...
  • @Patil,教科书是为想要快速使用该语言的人准备的,他们不倾向于深入研究这些方面。他们的衡量标准是让某人从非程序员变得足够,而不是足以成为大师。要理解这些方面,你需要花 30 年时间使用这门语言,检查它的阴暗角落,并经常被它烫伤:-)
  • 您想要这本书 C:Samuel Harbison 和 Guy Steele 的参考手册。它告诉你所有关于 C 的信息,而不是用不可读的标准语言编写。
【解决方案2】:

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

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

struct this_is_incomplete;

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

int some_function(struct this_is_incomplete* ptr);

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

【讨论】:

  • 但我们需要在sizeof操作符中提及struct temp。
  • 我感觉在做什么typedef struct temp { int i; char ch;int j;}Temp; 我可以得到尺寸,但是提到sizeof(temp) 我无法得到尺寸。这意味着,temp 不是一个完整的类型。是这样吗?
  • sizeof(temp) 在您的上下文中没有任何意义,因为temp 不是一个东西。 temp != struct temp (除非你 typedef 它。)sizeof(struct temp) 会给你尺寸。
  • 谢谢@JimBalter,我完全错过了。
【解决方案3】:

当一个类型声明了它的名字而不是它的定义时,它可能是不完整的。当您在头文件中前向声明类型时会发生这种情况。

说,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

类型record_t在“usage.c”编译单元中是不完整的,因为它只知道名称record_t,而不知道类型是由什么组成的。

【讨论】:

  • 由于问题标记为 C 和 C++,因此可能值得一提的是您的示例是 C++。
猜你喜欢
  • 2016-10-06
  • 2012-11-18
  • 2016-12-07
  • 2017-01-08
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多