我正在编写一个结构来描述我需要的常量值,并注意到一些奇怪的东西。
namespace res{
namespace font{
struct Structure{
struct Glyph{
int x, y, width, height, easement, advance;
};
int glyphCount;
unsigned char asciiMap[]; // <-- always generates an error
Glyph glyphData[]; // <-- never generates an error
};
const Structure system = {95,
{
// mapping data
},
{
// glyph spacing data
}
}; // system constructor
} // namespace font
} // namespace res
Structure
的最后两个成员,即未编译的数组,如果它们本身就不会停止编译器。但如果它们都包含在结构的定义中,则会导致错误,说“类型不完整”
如果我给第一个数组一个大小,这就不会有问题了。在这种情况下哪个不是问题,但我仍然好奇......
我的问题是,为什么我的结构中有一个未经过类型化的数组,但有两个会导致问题?
答案 0 :(得分:5)
在标准C ++中,你完全不能这样做,尽管有些编译器支持它作为扩展。
在C中,struct
的每个成员都需要在struct
内拥有固定的位置。这意味着 last 成员可能具有未知大小;但是没有任何东西可以追随它,因此没有办法拥有一个以上未知大小的成员。
如果您确实利用编译器对C ++中的这种黑客的非标准支持,那么请注意,如果struct
的任何成员都是非平凡的,那么事情可能会出现严重错误。通过分配一块原始内存并将其重新解释为此类型,只能在末尾使用非空数组“创建”对象;如果你这样做,就不会调用构造函数或析构函数。
答案 1 :(得分:3)
您正在使用non-standard microsoft extension。 C11(注意:C,而不是C ++)允许结构化中的最后一个数组(读取:一个数组的最大):
Microsoft扩展允许C或C ++结构或类的最后一个成员是可变大小的数组。这些称为unsized数组。结构末尾的unsized数组允许您附加一个可变大小的字符串或其他数组,从而避免指针取消引用的运行时执行成本。
// unsized_arrays_in_structures1.cpp // compile with: /c struct PERSON { unsigned number; char name[]; // Unsized array };
如果将sizeof运算符应用于此结构,则结束数组大小将被视为0.此结构的大小为2个字节,即无符号成员的大小。要获得PERSON类型变量的真实大小,您需要单独获取数组大小。
将结构的大小添加到数组的大小以获得要分配的总大小。分配后,数组被复制到结构的数组成员,如下所示:
答案 2 :(得分:2)
编译器需要能够决定结构中每个成员的偏移量。这就是为什么你不允许在未经过大小调整的数组之后放置任何的其他成员。由此可见,你不能在结构中有两个未经过类型化的数组。
答案 3 :(得分:1)
这是extension from Microsoft和sizeof(structure) == sizeof(structure_without_variable_size_array)
。
我猜他们使用初始化程序来查找数组的大小。如果你有两个可变大小的数组,你找不到它(相当于找到一个只有1个方程的2个未知系统的唯一解决方案......)
答案 4 :(得分:1)
struct
中不允许没有维度的数组,
期间,至少在C ++中。在C中,最后成员(并且只有
可以声明没有维度和一些编译器
允许在C ++中使用它作为扩展,但你不应该依赖它
它(在严格的模式下,他们至少应该抱怨它)。
如果是最后一个,其他编译器也实现了相同的语义
element的维度为0(也是一个扩展,需要
严格模式下的诊断)。
将不完整的数组类型限制为最后一个的原因
元素很简单:任何跟随的偏移量是多少
元素?即使它是最后一个元素,也有
使用结果结构的限制:它不可能
例如,另一个结构或数组的成员
sizeof
忽略了最后一个元素。