Kei*_*son 42
C中的数组大小没有固定限制.
任何单个对象(包括任何数组对象)的大小都受SIZE_MAX
类型的最大值的限制size_t
,这是sizeof
运算符的结果.(目前还不完全清楚C标准是否允许大于SIZE_MAX
字节的对象,但实际上这些对象不受支持;参见脚注.)由于SIZE_MAX
是由实现决定的,并且不能被任何程序修改,因此强加了SIZE_MAX
字节的上限对于任何单个对象.(这是一个上限,而不是一个上限;实现可能,通常会,施加更小的限制.)
类型的宽度(void*
通用指针类型)对执行程序中所有对象的总大小施加上限(可能大于单个对象的最大大小).
C标准对这些固定大小施加下限但不上限.没有符合要求的C实现可以支持无限大小的对象,但它原则上可以支持任何有限大小的对象.上限是由单个C实现,它们运行的环境以及物理而不是语言强加的.
例如,一致的实现可以具有SIZE_MAX
等于2 1024 -1,这意味着它可以在原理上有对象高达179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137215个字节.
祝你找到真正支持这些对象的硬件.
脚注:没有明确的规则,没有对象可以大于SIZE_MAX
字节.您无法将sizeof
运算符应用于此类对象,但与任何其他运算符一样,sizeof
可能会溢出; 这并不意味着你无法对这样的对象进行操作.但实际上,任何理智的实现都会size_t
足以表示它支持的任何对象的大小.
C99 5.2.4.1"翻译限制"最小尺寸
实现应能够翻译和执行至少一个包含以下每个限制的至少一个实例的程序:13)
- 对象中的65535个字节(仅限托管环境中)
13)实施应尽可能避免强加固定的翻译限制.
这表明一致的实现可以拒绝编译具有多于short
字节的对象(包括数组).
PTRDIFF_MAX
似乎是静态数组对象的实际限制
C99标准6.5.6添加剂运营商说:
9当减去两个指针时,两个指针都指向同一个数组对象的元素,或者指向数组对象的最后一个元素的元素; 结果是两个数组元素的下标的差异.结果的大小是实现定义的,其类型(有符号整数类型)
ptrdiff_t
在<stddef.h>
头文件中定义.如果结果在该类型的对象中无法表示,则行为未定义.
这对我来说意味着大于ptrdiff_t
理论上允许的数组,但是你不能把它们的地址区别开来.
所以也许是因为这个原因,海湾合作委员会似乎只限制你ptrdiff_t
.这也在下面提到:为什么数组的最大大小"太大"?
我凭经验证实了这一点main.c
:
#include <stdint.h>
uint8_t a[(X)];
int main(void) {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然后在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.
$ printf '
> #include <stdint.h>
> PTRDIFF_MAX
> SIZE_MAX
> ' | arm-linux-gnueabi-cpp | tail -n2
(2147483647)
(4294967295U)
$ PTRDIFF_MAX == 2147483647 == 2^31 - 1
$
$ # 2lu << 30 == 2^31 == PTRDIFF_MAX + 1
$ arm-linux-gnueabi-gcc -std=c99 -DX='(2lu << 30)' main.c
a.c:5:9: error: size of array ‘a’ is too large
uint8_t a[(X)];
^
$
$ # PTRDIFF_MAX
$ arm-linux-gnueabi-gcc -std=c99 -DX='(2lu << 30) - 1lu' main.c
$
Run Code Online (Sandbox Code Playgroud)
也可以看看
理论上,64位机器最多可以处理2 ^ 64字节的内存.
归档时间: |
|
查看次数: |
117638 次 |
最近记录: |