Andreas F. Borchert wrote:
> > I still don't know whether it's OK to have pointers to arrays with
> > 0 elements (which are not "array objects", since "objects" are non-
> > empty (§ 6.2.6.1.(2))).
>
> From § 6.7.6.2 about array declarators:
>
> If the expression is a constant expression, it shall have a
> value greater than zero.
>
> Hence, arrays must have at least one element. And in case of
> memory management functions, the behaviour is implementation-defined
> for a requested size of zero (see § 7.24.3) and null
> pointers are possible. Hence pointer arithmetic is not supported
> for pointers returned by malloc(0).
Thanks for the answer. But I'm talking about programs that access arrays
through pointers, not through array declarators. Such as this one:
==================================== foo.c ====================================
#include <stddef.h>
#include <stdlib.h>
#ifdef __GNUC__
# define unreachable() __builtin_unreachable ()
#endif
typedef struct { int a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t; } foo;
int main ()
{
char *m = malloc (1);
if (m == NULL)
unreachable ();
foo *p = (foo *) m; /* CAST */
ptrdiff_t d = p - p; /* DIFFERENCE */
foo *q = p + 0; /* ADDITION */
free (m);
}
/* gcc
-fsanitize=address,undefined,signed-integer-overflow,shift,integer-divide-by-zero
foo.c */
/* clang
-fsanitize=address,undefined,signed-integer-overflow,shift,integer-divide-by-zero
foo.c */
===============================================================================
gcc's and clang's sanitizers let this program pass at runtime.
The line /* CAST */ is probably OK because ISO C 23 § 6.5.4 specifies no
undefined behaviour.
The lines /* DIFFERENCE */ and /* ADDITION */ could be construed as undefined
behaviour according to ISO C 23 § 6.5.6.(9) and § 6.5.6.(10), but the sanitizers
don't flag it. Why?
Bruno