I found that an result of pointer subtraction in a big array is negative when
it is expected to be positive.

% cat t.i
typedef int ptrdiff_t;
typedef unsigned int size_t;
extern void *malloc (size_t __size) __attribute__ ((__malloc__));
extern void exit (int __status) __attribute__ ((__noreturn__));
extern int printf (__const char *__restrict __format, ...);
extern void perror (__const char *__s);

int main(int argc, char **argv)
{
  long *p, *q;
  int nelem;
  ptrdiff_t s;

  printf("sizeof(long) = %d\n", sizeof(long));
  printf("sizeof(size_t) = %d\n", sizeof(size_t));
  printf("sizeof(ptrdiff_t) = %d\n", sizeof(ptrdiff_t));

  nelem = 513 * 1024 * 1024;
  printf("nelem: %d\n", nelem);

  q = malloc(sizeof(long) * nelem);
  if (!q) { perror("malloc"); exit(1); }

  p = q + (nelem-1);
  s = p - q;
  printf("result: %d\n", s);

  return 0;
}
% bin/gcc -Wall t.i
% ./a.out 
sizeof(long) = 4
sizeof(size_t) = 4
sizeof(ptrdiff_t) = 4
nelem: 537919488
result: -535822337
% uname -srv
Linux 2.6.23.12 #3 SMP PREEMPT Thu Dec 27 21:28:19 JST 2007

This program allocates a big array, 513  * 1024 * 1024 elements of longs.

After that, the program subtracts the pointer to the first element from the
last element.

Then the subtraction from the pointer to one after the last element by the
pointer to the first element.
It's result should be 513 * 1024 * 1024 - 1. 
But -535822337 is printed.

Note that the expected result is representable in int because it is counted as
number of longs, not chars.


-- 
           Summary: pointer subtraction in very big array
           Product: gcc
           Version: 4.2.3
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: akr at m17n dot org
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35427

Reply via email to