我有一个还没有成员的结构体,想知道是否有可能抑制我得到的警告:
warning: struct has no members
是否可以添加一个成员并保持结构体的sizeof
为零?是否有其他解决方案?
我有一个还没有成员的结构体,想知道是否有可能抑制我得到的警告:
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标准。 您必须使用特定于编译器的扩展来抑制它。
void*
指针吗? void * var;
可以指向任何类型的变量,并且可以使用malloc
初始化动态元素集合,这个解决方案怎么样?我已经尝试过了,但需要进行很多类型转换。 - R1S8Ktsk_args = malloc(2*sizeof(uint8_t)+1*sizeof(unsigned char*));
其中 tsk_args
是指向 void 的指针。 - R1S8Kstruct zero_information { int:0; };
sizeof(struct zero_information)
产生一个非零值,但它可能会帮助您获得您所寻找的东西,因为分配给它的所有存储空间都是填充的(只能通过黑客访问,尽管我不记得从头顶上访问填充是否未定义行为)。int:0;
是什么意思?能否解释一下? - Mehdi CharifeC99标准在这个问题上有些模糊,但似乎表明一个空结构应该具有非零大小。
6.2.6.1 除了位域之外,对象由一个或多个字节的连续序列组成,其数量、顺序和编码要么明确指定,要么是实现定义的。
是否可以添加一个成员并保持结构体大小为零?
不可以。顺便提一下,C++允许空结构体,但空结构体的sizeof()值始终为非零。
还有其他解决方案吗?
没有简单的解决方案。值得注意的是,在C中只有部分支持空结构体,在C99中是不允许的。
空结构体在C++中得到支持,但不同的编译器实现它们的结果也不同(对于sizeof和结构偏移量),特别是当您开始将继承引入其中时。
struct empty {
char nothing[0];
};
struct empty99
{
char nothing[]; // This is a C99 "flexible array".
};