18

我有一个没有成员的结构(目前),我想知道是否可以抑制我收到的警告:

warning: struct has no members

是否可以添加成员并将sizeof结构保持为零?还有其他解决方案吗?

4

7 回答 7

26

在 c 中,空结构的行为取决于编译器,而 c++ 是规范的一部分(这里有解释

C++
具有空成员序列和基类对象的类是空类。空类类型的完整对象和成员子对象应具有非零大小。

在 C 中,它相当模糊,因为 c99 标准有一些语言暗示不允许真正的空结构(请参阅 TrayMan 的答案),但许多编译器确实允许它(例如gcc)。

由于这取决于编译器,因此在这种情况下您不太可能获得真正可移植的代码。因此,抑制警告的非便携式方式可能是您最好的选择。

于 2009-04-16T09:17:22.613 回答
21

如果您只需要用于转换和函数参数的结构符号,那么只需:

typedef struct _Interface Interface;

这将为不透明类型创建符号。

于 2011-05-26T09:53:27.650 回答
15

从技术上讲,这甚至不是有效的 C.

TrayMan 的分析有点偏离,是的 6.2.6.1 说:

除了位域,对象由一个或多个字节的连续序列组成,其数量、顺序和编码要么明确指定,要么由实现定义。

但将其与 6.2.5-20 联系起来,它说:

结构类型描述了一组顺序分配的非空成员对象(在某些情况下,还描述了一个不完整的数组),每个对象都有一个可选的指定名称和可能的不同类型。

现在您可以得出结论,结构将是一个或多个字节,因为它们不能为空。您的代码向您发出警告,而相同的代码实际上将无法在 Microsoft 的 Visual Studio 上编译并出现错误:

错误 C2016:C 要求结构或联合至少有一个成员

所以简短的回答是否定的,没有一种可移植的方法来避免这个警告,因为它告诉你你违反了 C 标准。您必须使用编译器特定的扩展来抑制它。

于 2013-03-14T17:30:21.250 回答
5

C99 标准对此有些模棱两可,但似乎说空结构应该具有非零大小。

6.2.6.1 除位域外,对象由一个或多个字节的连续序列组成,其数量、顺序和编码要么明确指定,要么由实现定义。

于 2009-04-16T09:27:10.607 回答
5
struct zero_information { int:0; };

上面的代码片段将从 中产生一个非零sizeof(struct zero_information),但它可能会帮助您获得所需的内容,因为为其分配的所有存储的 100% 是填充(只能通过 hack 访问,尽管我不记得了如果加入填充是未定义的行为,请从我的头顶开始)。

于 2013-05-10T09:37:28.103 回答
3

是否可以添加一个成员并将结构的大小保持为零?

没有。FWIW,C++ 允许空结构,但 sizeof() 对于空结构始终为非零。

还有其他解决方案吗?

不是任何容易的。值得注意的是,空结构在 C 中仅受到一定程度的支持,而在 C99 中则不允许。

C++ 支持空结构,但不同的编译器以不同的结果实现它们(对于 sizeof 和结构偏移),尤其是当您开始将继承混入其中时。

于 2009-05-28T08:08:45.730 回答
2

如果您不需要“过于严格”的遵守,您可能会逃脱:

struct empty {
  char nothing[0];
};

不过,这是一个GCC 扩展

我有点希望我能够使用称为“灵活数组”的 C99 功能,声明如下:

struct empty99
{
  char nothing[]; // This is a C99 "flexible array".
};

但这不起作用;他们要求至少有一个普通的结构成员,他们不能是唯一的成员。

于 2009-04-16T09:14:43.803 回答