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




Reply via email to