我有一个没有成员的结构(目前),我想知道是否可以抑制我收到的警告:
warning: struct has no members
是否可以添加成员并将sizeof
结构保持为零?还有其他解决方案吗?
在 c 中,空结构的行为取决于编译器,而 c++ 是规范的一部分(这里有解释)
C++
具有空成员序列和基类对象的类是空类。空类类型的完整对象和成员子对象应具有非零大小。
在 C 中,它相当模糊,因为 c99 标准有一些语言暗示不允许真正的空结构(请参阅 TrayMan 的答案),但许多编译器确实允许它(例如gcc)。
由于这取决于编译器,因此在这种情况下您不太可能获得真正可移植的代码。因此,抑制警告的非便携式方式可能是您最好的选择。
如果您只需要用于转换和函数参数的结构符号,那么只需:
typedef struct _Interface Interface;
这将为不透明类型创建符号。
从技术上讲,这甚至不是有效的 C.
TrayMan 的分析有点偏离,是的 6.2.6.1 说:
除了位域,对象由一个或多个字节的连续序列组成,其数量、顺序和编码要么明确指定,要么由实现定义。
但将其与 6.2.5-20 联系起来,它说:
—结构类型描述了一组顺序分配的非空成员对象(在某些情况下,还描述了一个不完整的数组),每个对象都有一个可选的指定名称和可能的不同类型。
现在您可以得出结论,结构将是一个或多个字节,因为它们不能为空。您的代码向您发出警告,而相同的代码实际上将无法在 Microsoft 的 Visual Studio 上编译并出现错误:
错误 C2016:C 要求结构或联合至少有一个成员
所以简短的回答是否定的,没有一种可移植的方法来避免这个警告,因为它告诉你你违反了 C 标准。您必须使用编译器特定的扩展来抑制它。
C99 标准对此有些模棱两可,但似乎说空结构应该具有非零大小。
6.2.6.1 除位域外,对象由一个或多个字节的连续序列组成,其数量、顺序和编码要么明确指定,要么由实现定义。
struct zero_information { int:0; };
上面的代码片段将从 中产生一个非零值sizeof(struct zero_information)
,但它可能会帮助您获得所需的内容,因为为其分配的所有存储的 100% 是填充(只能通过 hack 访问,尽管我不记得了如果加入填充是未定义的行为,请从我的头顶开始)。
是否可以添加一个成员并将结构的大小保持为零?
没有。FWIW,C++ 允许空结构,但 sizeof() 对于空结构始终为非零。
还有其他解决方案吗?
不是任何容易的。值得注意的是,空结构在 C 中仅受到一定程度的支持,而在 C99 中则不允许。
C++ 支持空结构,但不同的编译器以不同的结果实现它们(对于 sizeof 和结构偏移),尤其是当您开始将继承混入其中时。
如果您不需要“过于严格”的遵守,您可能会逃脱:
struct empty {
char nothing[0];
};
不过,这是一个GCC 扩展。
我有点希望我能够使用称为“灵活数组”的 C99 功能,声明如下:
struct empty99
{
char nothing[]; // This is a C99 "flexible array".
};
但这不起作用;他们要求至少有一个普通的结构成员,他们不能是唯一的成员。