C 结构有大小限制吗?

发布于 2024-12-09 02:56:01 字数 18 浏览 3 评论 0原文

C 结构有大小限制吗?

Are there any size limitations for C structures?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

愁以何悠 2024-12-16 02:56:01

从C标准来看:

5.2.4.1 翻译限制

1 实现应至少能够翻译和执行
一个程序至少包含其中每一个的一个实例
以下限制:

...
— 对象中 65535 字节(仅在托管环境中)
...
— 单个结构或联合中有 1023 个成员
...
— 63 层嵌套结构或联合定义
结构声明列表
...
13)实施应避免施加固定的翻译限制
只要有可能。

除此之外,上限为 SIZE_MAXsize_t 的最大值)。

From the C standard:

5.2.4.1 Translation limits

1 The implementation shall be able to translate and execute at least
one program that contains at least one instance of every one of the
following limits:

...
— 65535 bytes in an object (in a hosted environment only)
...
— 1023 members in a single structure or union
...
— 63 levels of nested structure or union definitions in a single
struct-declaration-list
...
13) Implementations should avoid imposing fixed translation limits
whenever possible.

Other than that, the upper bound is SIZE_MAX (maximum value for size_t).

何以畏孤独 2024-12-16 02:56:01

由于 sizeof 运算符生成 size_t 类型的结果,因此限制应为 SIZE_MAX

您可以像这样确定 SIZE_MAX 的值:

#include <stdint.h>
#include <stdio.h>

int main (void) {
  printf("%zu", SIZE_MAX);
  return 0;
}

这是编译器应该允许的。运行时环境允许什么是另一个故事。

实际上,在堆栈上(本地)声明类似大小的对象是行不通的,因为堆栈可能比 SIZE_MAX 小得多。

全局拥有这样的对象可能会使可执行加载程序在程序启动时抱怨。

Since the sizeof operator yields a result of type size_t, the limit should be SIZE_MAX.

You can determine the value of SIZE_MAX like this:

#include <stdint.h>
#include <stdio.h>

int main (void) {
  printf("%zu", SIZE_MAX);
  return 0;
}

This is what the compiler should allow. What the runtime environment allows is another story.

Declaring a similarly sized object on the stack (locally) in practice will not work since the stack is probably much, much smaller than SIZE_MAX.

Having such an object globally might make the executable loader complain at program startup.

冰火雁神 2024-12-16 02:56:01

经验分析

在实践中,像 GCC 这样的实现似乎只允许小于 size_t 的结构,可能受 PTRDIFF_MAX 的约束。另请参阅:最大大小是多少C 中的数组?

使用:

 for i in `seq 32`; do printf "typedef struct { S$i x; S$i y; } S$(($i+1));\n"; done

我们编写程序:

#include <stdint.h>
#include <stdio.h>

typedef struct { uint8_t i; } S0;
typedef struct { S0 x; S0 y; } S1;
typedef struct { S1 x; S1 y; } S2;
typedef struct { S2 x; S2 y; } S3;
typedef struct { S3 x; S3 y; } S4;
typedef struct { S4 x; S4 y; } S5;
typedef struct { S5 x; S5 y; } S6;
typedef struct { S6 x; S6 y; } S7;
typedef struct { S7 x; S7 y; } S8;
typedef struct { S8 x; S8 y; } S9;
typedef struct { S9 x; S9 y; } S10;
typedef struct { S10 x; S10 y; } S11;
typedef struct { S11 x; S11 y; } S12;
typedef struct { S12 x; S12 y; } S13;
typedef struct { S13 x; S13 y; } S14;
typedef struct { S14 x; S14 y; } S15;
typedef struct { S15 x; S15 y; } S16;
typedef struct { S16 x; S16 y; } S17;
typedef struct { S17 x; S17 y; } S18;
typedef struct { S18 x; S18 y; } S19;
typedef struct { S19 x; S19 y; } S20;
typedef struct { S20 x; S20 y; } S21;
typedef struct { S21 x; S21 y; } S22;
typedef struct { S22 x; S22 y; } S23;
typedef struct { S23 x; S23 y; } S24;
typedef struct { S24 x; S24 y; } S25;
typedef struct { S25 x; S25 y; } S26;
typedef struct { S26 x; S26 y; } S27;
typedef struct { S27 x; S27 y; } S28;
typedef struct { S28 x; S28 y; } S29;
typedef struct { S29 x; S29 y; } S30;
/*typedef struct { S30 x; S30 y; } S31;*/
S30 s;

int main(void) {
    printf("%jx\n", (uintmax_t)sizeof(s));
    return 0;
}

然后在 Ubunbu 17.10 中:

$ arm-linux-gnueabi-gcc --version
arm-linux-gnueabi-gcc (Ubuntu/Linaro 7.2.0-6ubuntu1) 7.2.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ arm-linux-gnueabi-gcc -std=c99 main.c

可以运行。但是,如果我们取消注释 S31,则会失败:

main.c:35:16: error: type ‘struct <anonymous>’ is too large
typedef struct { S30 x; S30 y; } S31;

因此​​最大大小介于 2^30 和 (2^31 - 1) 之间。

然后我们可以将 S30 转换为:

typedef struct { S29 x; S29 y; uint8_t a[(2lu << 29) - 1]; } S30;

并由此确定在此实现上的最大大小实际上是 2^31 - 1 == PTRDIFF_MAX

Empirical analysis

In practice, implentations like GCC seem to only allow structs smaller than size_t, perhaps bound by PTRDIFF_MAX. See also: What is the maximum size of an array in C?

Using:

 for i in `seq 32`; do printf "typedef struct { S$i x; S$i y; } S$(($i+1));\n"; done

We make the program:

#include <stdint.h>
#include <stdio.h>

typedef struct { uint8_t i; } S0;
typedef struct { S0 x; S0 y; } S1;
typedef struct { S1 x; S1 y; } S2;
typedef struct { S2 x; S2 y; } S3;
typedef struct { S3 x; S3 y; } S4;
typedef struct { S4 x; S4 y; } S5;
typedef struct { S5 x; S5 y; } S6;
typedef struct { S6 x; S6 y; } S7;
typedef struct { S7 x; S7 y; } S8;
typedef struct { S8 x; S8 y; } S9;
typedef struct { S9 x; S9 y; } S10;
typedef struct { S10 x; S10 y; } S11;
typedef struct { S11 x; S11 y; } S12;
typedef struct { S12 x; S12 y; } S13;
typedef struct { S13 x; S13 y; } S14;
typedef struct { S14 x; S14 y; } S15;
typedef struct { S15 x; S15 y; } S16;
typedef struct { S16 x; S16 y; } S17;
typedef struct { S17 x; S17 y; } S18;
typedef struct { S18 x; S18 y; } S19;
typedef struct { S19 x; S19 y; } S20;
typedef struct { S20 x; S20 y; } S21;
typedef struct { S21 x; S21 y; } S22;
typedef struct { S22 x; S22 y; } S23;
typedef struct { S23 x; S23 y; } S24;
typedef struct { S24 x; S24 y; } S25;
typedef struct { S25 x; S25 y; } S26;
typedef struct { S26 x; S26 y; } S27;
typedef struct { S27 x; S27 y; } S28;
typedef struct { S28 x; S28 y; } S29;
typedef struct { S29 x; S29 y; } S30;
/*typedef struct { S30 x; S30 y; } S31;*/
S30 s;

int main(void) {
    printf("%jx\n", (uintmax_t)sizeof(s));
    return 0;
}

and then in Ubunbu 17.10:

$ arm-linux-gnueabi-gcc --version
arm-linux-gnueabi-gcc (Ubuntu/Linaro 7.2.0-6ubuntu1) 7.2.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ arm-linux-gnueabi-gcc -std=c99 main.c

works. But if we uncomment S31, it fails with:

main.c:35:16: error: type ‘struct <anonymous>’ is too large
typedef struct { S30 x; S30 y; } S31;

So the maximum size is between 2^30 and (2^31 - 1).

Then we can convert S30 to:

typedef struct { S29 x; S29 y; uint8_t a[(2lu << 29) - 1]; } S30;

and with that we determine that the maximum size is actually 2^31 - 1 == PTRDIFF_MAX on this implementation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文