我无法猜测
等构造的用法struct
{
uint64_t offsets[0];
} table;
请给我一些暗示。
答案 0 :(得分:5)
您发布的代码正式无效。正式C语言不支持大小为0
的数组。
某些编译器(具有松散/遗留错误检查)允许在结构的末尾使用大小为零的数组,有时用于实现所谓的"struct hack"。 (更好的方法是使用大小为1的尾随数组。)但是,您的声明不提供该用法。 “struct hack”需要一个命名的struct类型,并且必须动态分配实际的对象。在您的情况下,结构类型未命名,变量table
是非动态定义的。因此,假设您正确地复制了代码,“struct hack”在这里是不可能的。
所以,即使它编译,你最终得到的变量table
也没有可用的数据。此变量的唯一用途(如果使用静态存储持续时间声明)是通过&table
表达式(“指向匿名结构的指针”类型的指针)生成唯一的地址常量。
将您的声明转换为更接近“struct hack”的方法的一种方法是在其前面添加typedef
typedef struct
{
uint64_t offsets[0];
} table;
然而,“struct hack”的“人工生成”结构声明通常会在灵活数组声明之前包含其他数据字段(没有它们,在普通数组中选择“struct hack”根本就没有意义)。
答案 1 :(得分:1)
这是一个技巧,允许您将任何大小的内存块转换为指针类型,并使最后一个数组成员成为可变长度数组。虽然可能不是标准的,但这可行,因为C数组未经过边界检查。
这是一个非常简单的例子:
typedef struct Foo
{
int count;
int array[0];
} Foo;
Foo* foo = (Foo*)malloc(sizeof(Foo) + 5 * sizeof(int));
foo->count = 5;
然后,您可以使用count
字段来了解Foo*
中有效元素的数量。因为,如上所述,C数组未经过边界检查,当您尝试读取或写入时,编译器和运行时都不会捕获foo->array
的大小为0。
答案 2 :(得分:0)
您已定义未命名的struct
实际上table
是对象而不是struct
名称。
所以,如果你有这个声明
typedef struct
{
uint64_t offsets[0];
} table;
或者,
struct table
{
uint64_t offsets[0];
} table;
然后,这称为可变长度数组(称为 struct hack )。
有限制,它应该是结构的最后一个成员。