每个结构只允许一个不允许大小的数组

Only one array without a size allowed per struct?

本文关键字:数组 不允许 许一个 结构      更新时间:2023-10-16

我正在编写一个结构来描述我需要的常量值,发现了一些奇怪的东西。

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的最后两个成员,即未定大小的数组,如果它们单独存在,则不会停止编译器。但是,如果它们包含在结构的定义中,则会导致错误,称"类型不完整">

如果我给第一个数组一个大小,这就不再是一个问题了。在这种情况下这不是问题,但我仍然很好奇。。。

我的问题是,为什么我的结构中可以有一个未大小的数组,但两个数组会导致问题?

在标准C++中,您根本无法做到这一点,尽管有些编译器支持将其作为扩展。

在C中,struct的每个成员都需要在struct内具有固定的位置。这意味着最后一个成员的大小可能未知;但它之后什么都不会发生,所以不可能有一个以上未知大小的成员。

如果您确实利用了编译器对C++中这种破解的非标准支持,那么请注意,如果struct的任何成员都是非平凡的,那么事情可能会出错。一个对象只能通过分配一块原始内存并将其重新解释为这种类型来"创建"末尾有一个非空数组的对象;如果这样做,就不会调用构造函数或析构函数。

您使用的是非标准的microsoft扩展。C11(注意:C,而不是C++(允许结构中的最后一个数组取消大小(读取:一个数组的最大值(:

Microsoft扩展允许C或C++结构或类的最后一个成员是可变大小的数组。这些称为无大小数组。结构末尾的无大小数组允许您附加可变大小的字符串或其他数组,从而避免指针取消引用的运行时执行成本。

// unsized_arrays_in_structures1.cpp
// compile with: /c
struct PERSON {
   unsigned number;
   char name[];   // Unsized array
};

如果将sizeof运算符应用于此结构,则结束数组的大小将被视为0。此结构的大小为2个字节,即无符号成员的大小。要获得PERSON类型变量的真实大小,您需要单独获得数组大小。

将结构的大小添加到数组的大小,以获得要分配的总大小。分配后,数组被复制到结构的数组成员中,如下所示:

编译器需要能够决定结构中每个成员的偏移量。这就是为什么不允许将任何进一步的成员放在未定大小的数组之后的原因。由此可知,在一个结构中不能有两个未大小的数组。

它是Microsoft和sizeof(structure) == sizeof(structure_without_variable_size_array)的扩展。

我猜他们使用初始值设定项来查找数组的大小。如果你有两个可变大小的数组,你就找不到它(相当于找到一个只有1个方程的2-未知系统的唯一解…(

struct中不允许使用没有维度的数组,周期,至少在C++中是这样。在C中,最后一个成员(并且只有last(可以在没有维度的情况下声明,并且一些编译器允许在C++中这样做,作为扩展,但你不应该指望(在严格的模式下,他们至少应该抱怨一下(。其他编译器已经实现了相同的语义,如果元素的维度为0(也是一个扩展,需要严格模式下的诊断(。

将不完整的数组类型限制为最后一个的原因元素很简单:以下任何元素的偏移量是多少元素?即使是最后一个元素对使用结果结构的限制:它不能例如,另一个结构或数组的成员,以及sizeof忽略最后一个元素。