The maximum number of elements in an array object in C is PTRDIFF_MAX.
Long story:
The ISO C standard says that an implementation must support objects of at least 2^16 - 1 bytes. This is of course not the actual limit.
The standard specifies that it is valid to subtract two pointers that point to different elements of the same array object, and that the result is of ptrdiff_t type. This implies that the number of elements in an array object must be representable in a ptrdiff_t, and so the maximum number of elements in an array object is implicitly defined as not larger than PTRDIFF_MAX.
Since both the compiler and libc usually have to access objects as raw bytes, they'll also have to subtract pointers to bytes, and so the limit is further restricted to just PTRDIFF_MAX bytes (not just elements).
Here's some proof that the compiler doesn't allow objects larger than PTRDIFF_MAX bytes:
$ cat huge.c
#include <stdint.h>
int
main(void)
{
char a[PTRDIFF_MAX - 1];
char b[PTRDIFF_MAX];
char c[PTRDIFF_MAX + 1ul];
int d[PTRDIFF_MAX - 1];
int e[PTRDIFF_MAX];
int f[PTRDIFF_MAX + 1ul];
int g[PTRDIFF_MAX/4 - 1];
int h[PTRDIFF_MAX/4];
int i[PTRDIFF_MAX/4 + 1];
}
$ cc -Wall -Wextra huge.c -Wno-unused-variable
huge.c: In function ‘main’:
huge.c:8:15: error: size of array ‘c’ is too large
8 | char c[PTRDIFF_MAX + 1ul];
| ^
huge.c:10:15: error: size of array ‘d’ exceeds maximum object size ‘9223372036854775807’
10 | int d[PTRDIFF_MAX - 1];
| ^
huge.c:11:15: error: size of array ‘e’ exceeds maximum object size ‘9223372036854775807’
11 | int e[PTRDIFF_MAX];
| ^
huge.c:12:15: error: size of array ‘f’ is too large
12 | int f[PTRDIFF_MAX + 1ul];
| ^
huge.c:16:15: error: size ‘9223372036854775808’ of array ‘i’ exceeds maximum object size ‘9223372036854775807’
16 | int i[PTRDIFF_MAX/4 + 1];
| ^
Thus, whether implementations want to recognize it or not, objects have size limits. If an implementation claims that there's no limit, it's probably lying or unaware of its own limitations.
Let's hard code a strong limit of MIN(whatever, PTRDIFF_MAX).
https://github.com/shadow-maint/shadow/blob/63297e836d000db7928b02cf9608796346705611/lib/chkname.c#L36-L48
Cc: @stoeckmann
The maximum number of elements in an array object in C is
PTRDIFF_MAX
.Long story:
The ISO C standard says that an implementation must support objects of at least
2^16 - 1
bytes. This is of course not the actual limit.The standard specifies that it is valid to subtract two pointers that point to different elements of the same array object, and that the result is of
ptrdiff_t
type. This implies that the number of elements in an array object must be representable in aptrdiff_t
, and so the maximum number of elements in an array object is implicitly defined as not larger thanPTRDIFF_MAX
.Since both the compiler and libc usually have to access objects as raw bytes, they'll also have to subtract pointers to bytes, and so the limit is further restricted to just
PTRDIFF_MAX
bytes (not just elements).Here's some proof that the compiler doesn't allow objects larger than
PTRDIFF_MAX
bytes:https://discourse.llvm.org/t/problems-with-objects-larger-than-ptrdiff-max/41126/6
Thus, whether implementations want to recognize it or not, objects have size limits. If an implementation claims that there's no limit, it's probably lying or unaware of its own limitations.
Let's hard code a strong limit of
MIN(whatever, PTRDIFF_MAX)
.