引自C-std部分6.7.2.1,
struct s { int n; double d[]; };
Run Code Online (Sandbox Code Playgroud)
这是一个有效的结构声明.我正在寻找这种语法的一些实际用途.确切地说,这个构造如何比保持double*作为第二个元素更强或更弱?或者这是"你可以做多种方式"的另一种情况吗?
Arpan
考虑下面的C99结构,以灵活的数组成员结尾:
struct hdr
{
size_t len;
size_t free;
char buf[];
};
Run Code Online (Sandbox Code Playgroud)
len例如,使用这样的内联函数(放入头文件中)进行访问,并将其buf作为参数:
static inline size_t slen(const char *s)
{
struct hdr *h = (struct hdr*)(s - (int)offsetof(struct hdr, buf));
return h->len;
}
Run Code Online (Sandbox Code Playgroud)
这是库的一部分,将使用C编译器进行编译。但是,我想从C ++访问该库。这实质上意味着相应的头文件(带有适当的extern "C" {...}防护)必须是有效的C ++代码。一种可能的解决方案是slen在源代码主体中定义功能,而完全避免使用内联代码,但这不是最佳选择。
我的想法是定义一个有效的虚拟C ++结构,并且可以通过某种方式将其映射到hdr,例如
struct cpp_hdr
{
size_t len;
size_t free;
char buf[1];
}
Run Code Online (Sandbox Code Playgroud)
请注意,我只希望得到正确的(负)的偏移值len和free; 没有访问buf的意图。
现在我的问题是:是否有任何保证
static inline size_t slen(const char *s)
{
struct cpp_hdr *h = (struct cpp_hdr*)(s …Run Code Online (Sandbox Code Playgroud) 我最近在Rust上阅读了很多,但我仍然只是开始氧化.我的大脑保留了大部分的C/C++反应,所以请原谅我这个问题是不相关的,因为Rust的工作方式如何.
通常是否可能(希望?)在堆上分配任意大小的块,然后在其上映射数据结构,并使用较小块内存的绑定?
使用C99,可以写这个:
typedef unsigned char BYTE;
typedef struct {
size_t size;
BYTE payload[];
} flex;
// ...
flex * flex_new(size_t _size) {
flex *f = malloc(sizeof(flex) + _size * sizeof(BYTE));
f->size = _size;
return f;
}
Run Code Online (Sandbox Code Playgroud)
灵活长度数组可能证明是有用的,例如在实现具有可变大小的块的内存池时或者在专用于线程的堆上分配内存时.需要大小的数据结构仅在运行时已知,以"原子"方式分配,其成员连续打包.
我想知道类似的Rust实现是否可行(没有unsafe构造),如果是,它看起来像什么.也许编译器可能会使用struct定义中的生命周期说明符来推断一些信息?
正如标题所述,我想知道具有灵活数组成员的C结构数组如何表现.这是一个例子:
struct vector {
size_t length;
double array[];
};
Run Code Online (Sandbox Code Playgroud)
维基百科的文章说:
sizeof这种结构上的操作符需要给出柔性阵列成员的偏移量.
在我的机器上,这对应于8个字节(sizeof(size_t)).但是,当我执行以下操作时会发生什么:
显然,数组不能保存向量数据v0,因为它只有3*8字节= 24字节宽.我该如何处理这样的情况?
#define LENGTH 10
int main() {
struct vector arr[3];
struct vector *v0 = calloc(1, sizeof(*v0) + LENGTH * sizeof(v0->array[0]));
v0->length = LENGTH;
size_t i;
for (i = 0; i < v0->length; i++) {
v0->array[i] = (double) i;
}
struct vector v1;
struct vector v2;
arr[0] = *v0;
arr[1] = v1;
arr[2] = v2;
for (i = 0; …Run Code Online (Sandbox Code Playgroud) 海湾合作委员会 G++ 9
这段代码:
class foo {
int bar[] = {111, 123};
};
Run Code Online (Sandbox Code Playgroud)
产生有关灵活数组的初始值设定项的错误。但这一个:
class foo {
int bar[2] = {111, 123};
};
Run Code Online (Sandbox Code Playgroud)
正常编译。有什么解决方法可以不计算我输入的值吗?
以下内容应该对声明有效table_type,特别是e[]:
struct table_type
{
unsigned int8 a;
unsigned int8 b;
unsigned int8 c;
unsigned int8 d;
unsigned int8 e[];
};
struct table_type table[] =
{
{ 0, 1, 2, 3, { 4, 5, 6, 7, 8} },
{ 9, 10, 11, 12, { 13, 14, 15, 16, 17} },
{ 18, 19, 20, 21, { 22, 23, 24, 25, 26} },
{ 27, 28, 29, 30, { 31, 32, 33, 34, 35} },
{ 36, 37, …Run Code Online (Sandbox Code Playgroud) 在嵌套结构中有灵活的数组成员是有效的C代码吗?那么下面的示例代码是否可以通过合理的编译器按预期工作?
#include <stdio.h>
#include <stdlib.h>
struct d {
char c;
int ns[];
};
struct c {
struct d d;
};
struct b {
struct c c;
};
struct a {
int n;
struct b b;
};
int main() {
const int n = 10;
struct a *pa = malloc(sizeof(*pa) + n * sizeof(pa->b.c.d.ns[0]));
pa->n = n;
pa->b.c.d.c = 1;
for (int i = 0; i < n; ++i) {
pa->b.c.d.ns[i] = i;
}
for (int i = 0; i < …Run Code Online (Sandbox Code Playgroud) 我在联合中声明了一个灵活的数组成员,如下所示:
#include <stdio.h>
union ut
{
int i;
int a[]; // flexible array member
};
int main(void)
{
union ut s;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
和编译器给出一个错误:
source_file.c:8:9: error: flexible array member in union
int a[];
Run Code Online (Sandbox Code Playgroud)
但是,声明的数组零大小如下:
union ut
{
int i;
int a[0]; // Zero length array
};
Run Code Online (Sandbox Code Playgroud)
它工作正常.
为什么零长度阵列工作精细?
我对sizeof()C语言的输出感到困惑。说我有:
struct foo {
char a;
char b;
char c;
char d[0];
};
Run Code Online (Sandbox Code Playgroud)
我希望sizeof(struct foo)是4。但是,用gcc编译后返回3。另外,在使用严格的设置编译代码时-pedantic-errors,会出现编译器错误。
有人可以帮助我了解这种行为吗?
我已经在ISO C99委员会草案中看到,结构可能有一个不完整的数组,其末端具有未指定的大小,称为Flexible Array Member.
另一方面,C99还具有可变长度数组,它允许在编译时声明大小不恒定的数组.
我认为FAM是一种特殊的VLA,但我看到有两个SO用户声称不是.此外,阅读维基百科部分sizeof,它表示这sizeof两者的行为不同.
为什么它们都存在而不只是一个?(他们的用例太不一样了吗?)
此外,哪些其他相关行为对于每个行为都不同?