Is this a bad pointer bug?

Joe Buck jbuck@synopsys.com
Fri Jul 18 17:20:00 GMT 2003


On Fri, Jul 18, 2003 at 10:21:09AM -0400, Daniel Jacobowitz wrote:
> On Fri, Jul 18, 2003 at 07:12:13AM -0700, H. J. Lu wrote:
[ artificial pointer-subtraction example ]
> > What does C standard say on this?
> 
> That there's no bug.
> 
>        [#9]  When  two pointers are subtracted, both shall point to
>        elements of the same array object,  or  one  past  the  last
>        element of the array object; the result is the difference of
>        the subscripts of the two array elements.

GCC contains some clever number theory to avoid division operations in
cases like this: it must compute the address difference and divide it
by sizeof(struct foo).  If it is known b divides a evenly, it's possible
to compute a/b mod N with a multiplication and shift operations instead.
Here N is 2**32 on a 32-bit machine.  Consider the case where b is odd.
Then there is some number inv_b such that (inv_b * b) mod N is 1.  In
that case, (a/b) mod N is equal to (a*inv_b) mod N.  If b is even,
and it evenly divides a, then we apply enough right shifts to a and b
to get an odd denominator.

So, if the size of the struct is 44, we need to compute (diff/44) mod
2**32 on a 32-bit machine.  The first operation is a shift by two, so
we compute (diff_shift/11) mod 2**32.  We compute the inverse of 11
at compile time, giving a constant C such that C*11 mod 32 is 1.  It
turns out that C is 3123612579.  So the pointer subtraction code
has a shift-right by two and then an unsigned multiplication by C.

A consequence is that for invalid pointer subtractions (where the difference
is not a multiple of sizeof(T)) gcc will return nonsense, as it is allowed
to do.

the emitted 

 
> 
> -- 
> Daniel Jacobowitz
> MontaVista Software                         Debian GNU/Linux Developer

-- 
Q. What's more of a headache than a bug in a compiler.
A. Bugs in six compilers.  -- Mark Johnson



More information about the Gcc mailing list