Patch for strstr_binary

David Hopwood <>
Tue Dec 13 15:11:27 CET 2005


Dave Smith wrote:
> On Dec 12, 2005, at 7:53 PM, Mikael Pettersson wrote:
> 
>> This isn't ANSI-C and won't compile with e.g. gcc-2.95.3.
>> You should make a single block of the variable declarations
>> at the beginning of this scope, and do the initialisations
>> as assignments.
> 
> Fixed in attached patch. I've spent too long outside of strict C  world. :)
> 
>> These (int) casts are broken on 64-bit machines. Replace them
>> with (long) casts. Better yet, "index = cur - big_ptr;"
>> should have the same effect and be 100% kosher.
> 
> You have to cast pointers if you want an int out of them, at least 
> according to my version of gcc.

That's not correct, or you have a very old version of gcc:

#include <stdio.h>
#include <stddef.h>

int main(int argc, char **argv) {
    char foo[5];
    char *p = &foo[0];
    char *q = &foo[5];
    ptrdiff_t x = q - p;  /* works unconditionally */
    long      y = q - p;  /* works if 'long' is long enough */
    int       z = q - p;  /* works if 'int' is long enough */

    printf("%ld, %ld, %d\n", (long) x, y, z);
    return 0;
}

$ gcc -ansi -pedantic -Wall ptrsub.c -o ptrsub

$ gcc --version
gcc (GCC) 3.2 20020818 (prerelease)
Copyright (C) 2002 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ ./ptrsub
5, 5, 5

As far as I know, earlier releases of gcc behave the same.

> However, I did correct the casts to  be longs instead of ints.

Strictly speaking, casting a pointer to 'long' causes undefined behaviour.
There are platforms on which it will not work.

If you want something that produces an int provided the pointer difference
will fit in an int, use '(int)(cur - big_ptr)'. Or if it really matters
(for example if there is the potential for a security bug if the arithmetic
wraps):

#include <stddef.h>

    ptrdiff_t diff = cur - big_ptr;
    int index = (int) diff;
    if (diff != (ptrdiff_t) index) { /* fail */ }

-- 
David Hopwood <>




More information about the erlang-questions mailing list