Re: pointer-in-array test
Bernhard Holzmayer <holzmayer.bern hard@deadspam.c om> writes:
[color=blue]
> Dik T. Winter wrote:
>[color=green]
>> In article <1133145.9pkQ6i reiI@holzmayer. ifr.rt>
>> holzmayer.bernh ard@deadspam.co m writes: ...[color=darkred]
>> > What about this solution:
>> > int ptrInArrSafe(T *p,T *a,int max)
>> > /* check whether p points to an element of a[max] */
>> > {
>> > long px = (long)p;
>> > long ax = (long)a;
>> > if (px<ax) return 0; /*out*/
>> > if (px> (long)&a[max-1]) return 0; /* out */
>> > if ( (px-ax) % sizeof(T)) return 0; /* not at element
>> > start*/
>> > return 1; /* in and on element start */
>> > }
>> >
>> > compiles, links, runs without problems with my gcc.
>> > And, as far as I remember, it's legal, to compare pointers
>> > after conversion to long.[/color]
>>
>> But the result is implementation defined. I know of at least one
>> system where it will fail to give the correct answer, then T is
>> char. For instance:
>> (long)(a + 7) > (long)(a + 8)
>> when a is an array of type char.[/color]
>
> That's not the same.
> Would you please try the following:
> (long)(&a[7]) < (long)(&a[8])[/color]
The only difference between these expressions is that the first uses the
`>' operator, while the second uses the `<' operator. But `(long)(a+7)'
is exactly the same as `(long)(&a[7])' (likewise if both 7s are replaced
by 8s).
Also, trying something (in the sense of compiling and running it and
observing what it does) is a very flawed way to determine if something
is correct, as it does not necessarily give the right answer.
[color=blue]
> this should give the correct result.[/color]
The result of the conversion to `long' is implementation-defined, so it
cannot be correct on all possible implementations .
If `long' cannot represent the pointer value, the behavior is undefined.
[color=blue]
> Reason for your strange behaviour is possibly the implicite type
> cast,[/color]
C does not have implicit type casts. You mean conversion. :)
[color=blue]
> which converts a before adding.[/color]
There's no conversion before adding. This is the `+' operator between a
pointer and an integer type, which results in a pointer type.
[color=blue]
> Instead, the later version increments a as a pointer and then converts
> it.[/color]
So does the first.
Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Bernhard Holzmayer <holzmayer.bern hard@deadspam.c om> writes:
[color=blue]
> Dik T. Winter wrote:
>[color=green]
>> In article <1133145.9pkQ6i reiI@holzmayer. ifr.rt>
>> holzmayer.bernh ard@deadspam.co m writes: ...[color=darkred]
>> > What about this solution:
>> > int ptrInArrSafe(T *p,T *a,int max)
>> > /* check whether p points to an element of a[max] */
>> > {
>> > long px = (long)p;
>> > long ax = (long)a;
>> > if (px<ax) return 0; /*out*/
>> > if (px> (long)&a[max-1]) return 0; /* out */
>> > if ( (px-ax) % sizeof(T)) return 0; /* not at element
>> > start*/
>> > return 1; /* in and on element start */
>> > }
>> >
>> > compiles, links, runs without problems with my gcc.
>> > And, as far as I remember, it's legal, to compare pointers
>> > after conversion to long.[/color]
>>
>> But the result is implementation defined. I know of at least one
>> system where it will fail to give the correct answer, then T is
>> char. For instance:
>> (long)(a + 7) > (long)(a + 8)
>> when a is an array of type char.[/color]
>
> That's not the same.
> Would you please try the following:
> (long)(&a[7]) < (long)(&a[8])[/color]
The only difference between these expressions is that the first uses the
`>' operator, while the second uses the `<' operator. But `(long)(a+7)'
is exactly the same as `(long)(&a[7])' (likewise if both 7s are replaced
by 8s).
Also, trying something (in the sense of compiling and running it and
observing what it does) is a very flawed way to determine if something
is correct, as it does not necessarily give the right answer.
[color=blue]
> this should give the correct result.[/color]
The result of the conversion to `long' is implementation-defined, so it
cannot be correct on all possible implementations .
If `long' cannot represent the pointer value, the behavior is undefined.
[color=blue]
> Reason for your strange behaviour is possibly the implicite type
> cast,[/color]
C does not have implicit type casts. You mean conversion. :)
[color=blue]
> which converts a before adding.[/color]
There's no conversion before adding. This is the `+' operator between a
pointer and an integer type, which results in a pointer type.
[color=blue]
> Instead, the later version increments a as a pointer and then converts
> it.[/color]
So does the first.
Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Comment