PATCH: BPs & cleanups for ARRAY_SIZE

Greg McGary greg@mcgary.org
Wed Aug 23 13:49:00 GMT 2000


Alexandre Oliva <aoliva@redhat.com> writes:

> On Aug 23, 2000, Greg McGary <greg@mcgary.org> wrote:
> 
> >          -- An  array  subscript is out of range, even if an object
> >             is apparently accessible with the given  subscript  (as
> >             in  the lvalue expression a[1][7] given the declaration
> >             int a[4][5]) (6.5.6).

FYI...

       3.4.3
       undefined behavior
       behavior, upon use of a  nonportable  or  erroneous  program
       construct,  of  erroneous data, for which this International
       Standard  imposes  no requirements

       NOTE  Possible undefined behavior ranges from ignoring
       the situation  completely  with  unpredictable  results,  to
       behaving  during  translation  or  program  execution  in  a
       documented manner characteristic of the environment (with or
       without   the   issuance   of   a  diagnostic  message),  to
       terminating a translation or execution (with the issuance of
       a diagnostic message).

> Ok, this applies to array subscripts, but does it apply to pointers
> derived from the arrays too?  In particular, does it apply to char*s?

By inference, that must be undefined as well.  Note that undefined
simply means that the standard is mute on the behavior.  GCC is not
required to do anything in particular, and is free to silently make
the expected address calculation, as it does now.  BPs simply impose a
higher standard of conformity between definitions & uses, and
generates exceptions for this particular undefined construct.  Doing
it the BP-clean way does have virtue, since code that accesses via
proper subscripts will continue to work if a multi-dimensional array
is later converted to be an array of vectors.

Note that it is possible, through application of extra force, to make
BPs flatten a multi-dimensional array:

# define BOUNDED_N(PTR, N) 				\
  ({ __typeof (PTR) __bounded _p_;			\
     __ptrvalue _p_ = __ptrlow _p_ = __ptrvalue (PTR);	\
     __ptrhigh _p_ = __ptrvalue _p_ + (N);		\
     _p_; })

int a[10][10];
int *ap;

ap = BOUNDED_N ((int *) a, sizeof a / sizeof int);

... though I don't recommend the practice without compelling justification.

Greg


More information about the Gcc-patches mailing list