具有灵活数组成员的结构“数组”
“Array” of struct with flexible array member
我正在重写一些具有结构数组的旧代码,每个结构都有一个长度在编译时固定的数组成员。外部数组中的结构数量在编译时确定以适合(典型的)内存页。我想在 运行 时间创建内部数组变量,但保持“外部数组适合页面”逻辑不变(并使用 sysconf(_SC_PAGESIZE)
精确获取页面大小)。所以我的结构有一个灵活的数组成员
struct foo_t
{
bar_t *bar;
float baz[];
};
我想要这些东西的数组,但当然不允许。但是所有这些结构都将具有相同大小的灵活数组成员(运行-时间确定),那么我可以用它们的“数组”代替吗?也就是说,有一个 char *
有足够的 space 来适应其中的 n,我自己计算偏移量,然后将指针偏移量转换为 foo_t *
然后访问、修改、等
我的目标是C99,一推C11。
C 标准不支持这个。在实践中,可以计算出运行-次结构大小和元素位置:
#include <stddef.h>
typedef struct Unknown bar_t;
struct foo_t
{
bar_t *bar;
float baz[];
};
/* Calculate the size required for an array of struct foo_t objects in which
each flexible array member has NElements elements.
*/
size_t SizeOfFoo(size_t NElements)
{
/* Create an unused pointer to provide type information, notably the size
of the member type of the flexible array.
*/
struct foo_t *p;
/* Calculate the size of a struct foo_t plus NElements elements of baz,
without padding after the array.
*/
size_t s = offsetof(struct foo_t, baz) + NElements * sizeof p->baz[0];
// Calculate the size with padding.
s = ((s-1) / _Alignof(struct foo_t) + 1) * _Alignof(struct foo_t);
return s;
}
/* Calculate the address of the element with index Index in an “array” built
of struct foo_t objects in which each flexible array member has NElements
elements.
*/
struct foo_t *SubscriptFoo(void *Base, size_t NElements, ptrdiff_t Index)
{
return (struct foo_t *) ((char *) Base + Index * SizeOfFoo(NElements));
}
这可能存在一些语言法律问题,但我不希望它们影响实际的编译器。
我正在重写一些具有结构数组的旧代码,每个结构都有一个长度在编译时固定的数组成员。外部数组中的结构数量在编译时确定以适合(典型的)内存页。我想在 运行 时间创建内部数组变量,但保持“外部数组适合页面”逻辑不变(并使用 sysconf(_SC_PAGESIZE)
精确获取页面大小)。所以我的结构有一个灵活的数组成员
struct foo_t
{
bar_t *bar;
float baz[];
};
我想要这些东西的数组,但当然不允许。但是所有这些结构都将具有相同大小的灵活数组成员(运行-时间确定),那么我可以用它们的“数组”代替吗?也就是说,有一个 char *
有足够的 space 来适应其中的 n,我自己计算偏移量,然后将指针偏移量转换为 foo_t *
然后访问、修改、等
我的目标是C99,一推C11。
C 标准不支持这个。在实践中,可以计算出运行-次结构大小和元素位置:
#include <stddef.h>
typedef struct Unknown bar_t;
struct foo_t
{
bar_t *bar;
float baz[];
};
/* Calculate the size required for an array of struct foo_t objects in which
each flexible array member has NElements elements.
*/
size_t SizeOfFoo(size_t NElements)
{
/* Create an unused pointer to provide type information, notably the size
of the member type of the flexible array.
*/
struct foo_t *p;
/* Calculate the size of a struct foo_t plus NElements elements of baz,
without padding after the array.
*/
size_t s = offsetof(struct foo_t, baz) + NElements * sizeof p->baz[0];
// Calculate the size with padding.
s = ((s-1) / _Alignof(struct foo_t) + 1) * _Alignof(struct foo_t);
return s;
}
/* Calculate the address of the element with index Index in an “array” built
of struct foo_t objects in which each flexible array member has NElements
elements.
*/
struct foo_t *SubscriptFoo(void *Base, size_t NElements, ptrdiff_t Index)
{
return (struct foo_t *) ((char *) Base + Index * SizeOfFoo(NElements));
}
这可能存在一些语言法律问题,但我不希望它们影响实际的编译器。