0

我猜不出结构的使用,例如

struct 
{
    uint64_t offsets[0];
} table; 

请给我一些提示。

4

3 回答 3

5

您发布的代码正式无效。形式上 C 语言不支持 size 的数组0

一些编译器(带有松散/遗留错误检查)允许在结构末尾放置一个大小为零的数组,这有时用于实现所谓的“struct hack”。(更好的方法是使用大小为 1 的尾随数组。)但是,您的声明并未提供该用途。“结构破解”需要命名结构类型,并且必须动态分配实际对象。在您的情况下,结构类型未命名,并且变量table是非动态定义的。因此,假设您正确复制了代码,“struct hack”在这里是没有问题的。

因此,即使它编译,您最终也会得到table不包含可用数据的变量。这个变量的唯一用途(如果用静态存储持续时间声明)是通过&table表达式(“指向匿名结构的指针”类型的指针)产生一个唯一的地址常量。

将您的声明变成更接近“struct hack”的一种方法是typedef在它前面添加一个

typedef struct 
{
  uint64_t offsets[0];
} table; 

但是,“struct hack”的“人工生成”结构声明通常会在灵活数组声明之前包含其他数据字段(没有它们,在普通数组上选择“struct hack”根本没有意义)。

于 2012-12-25T06:50:11.250 回答
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 的数组。

于 2012-12-25T06:51:18.460 回答
0

您定义的未命名struct实际上table是对象而不是struct名称。

所以,如果你有这个声明

typedef struct 
{
    uint64_t offsets[0];
} table; 

或者,

   struct table
    {
        uint64_t offsets[0];
    } table; 

然后,这称为变长数组(称为struct hack)。

有一个限制,它应该是结构的最后一个成员。

有关它的更多信息,请参阅这篇关于 struct hack 的文章

于 2012-12-25T06:48:41.513 回答