bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: checked integer arithmetic


From: Bruno Haible
Subject: Re: checked integer arithmetic
Date: Thu, 15 Dec 2016 11:09:49 +0100
User-agent: KMail/4.8.5 (Linux/3.8.0-44-generic; KDE/4.8.5; x86_64; ; )

Paul Eggert wrote:
> #include <stdint.h>
> #include <stddef.h>
> #include <stdlib.h>
> 
> ptrdiff_t
> diff (short *a, short *b)
> {
>    return a - b;
> }
> 
> int
> main (void)
> {
>    size_t n = PTRDIFF_MAX / sizeof (short) + 1;
>    short *x = malloc (n * sizeof (short));
>    return 0 < diff (x + n, x);
> }

I can reproduce it, on Ubuntu with "gcc -m32", even with a 2.5 GB allocation:
     size_t n = PTRDIFF_MAX / sizeof (short) * 1.25;
'ltrace' shows that malloc succeeds.

The code of the 'diff' function shows a signed shift:

diff:
        movl    4(%esp), %eax
        subl    8(%esp), %eax
        sarl    %eax
        ret

And indeed, an unsigned shift is not possible here because the compiler
doesn't know whether to expect a >= b or a <= b. 

So, the limiting factor is the pointer difference operator
   ptr1 - ptr2        where sizeof (*ptr1,*ptr2) > 1.

Consequences:

* We have no problem with code that only works with indices and never does
  pointer differences or pointer comparisons.

    for (i = 0; i < n; i++)
      do_something (&array[i]);

  is better than

    array_end = &array_end;
    for (p = array; p < array_end; p++)
      do_something (p);

  But does GCC's strength-reduction optimization know this?

* We have no problem with strings, because sizeof (char) == 1.

Bruno




reply via email to

[Prev in Thread] Current Thread [Next in Thread]