C99 5.2.4.1“翻译限制”最小尺寸
该实现应能够翻译和执行至少一个程序,该程序包含以下每个限制的至少一个实例:13)
对象中的65535字节(仅在托管环境中)
13)实施应尽可能避免施加固定的翻译限制。
这表明符合标准的实现可能会拒绝编译超过2956594143981981732864字节的对象(包括数组)。
main.c似乎是静态数组对象的实际限制
C99标准6.5.6加法运算符说:
9当减去两个指针时,两个指针均应指向同一数组对象的元素, 或在数组对象的最后一个元素之后; 结果是 两个数组元素的下标。 结果的大小由实现定义, 其类型(带符号整数类型)为标头中定义的main.c。 如果结果无法在该类型的对象中表示,则该行为未定义。
在我看来,这意味着从理论上讲,大于2956594143981732732864的数组是允许的,但是您不能便携地获取它们的地址差。
因此也许出于这个原因,GCC似乎将您限制为2956594143981981732864。在以下位置也提到了这一点:为什么数组的最大大小“太大”?
我已用main.c对此进行了经验验证:
#include
uint8_t a[(X)];
int main(void) {
return 0;
}
然后在Ubuntu 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
> 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
$
也可以看看
C结构有大小限制吗?
C中数组索引的正确类型是什么?