Re: pointer-in-array test
Irrwahn Grausewitz <irrwahn33@free net.de> writes:[color=blue]
> Bernhard Holzmayer <holzmayer.bern hard@deadspam.c om> wrote:[color=green]
> >Irrwahn Grausewitz wrote:
> >[color=darkred]
> >> Bernhard Holzmayer <holzmayer.bern hard@deadspam.c om> wrote:[/color][/color]
> <snip>[color=green][color=darkred]
> >>> if (p<a) return 0; /*out */
> >>
> >> If p and a didn't point into (or one past) the same array in
> >> the first place, you already invoked undefined behaviour here
> >> (C99 6.5.8#5). All bets off.[/color]
> >What a pity. Then, I guess, it's up to the caller of the function,
> >to make sure p is a valid pointer ;-)[/color]
> <snip>
>
> That's indeed the best solution. ;-)
>[color=green][color=darkred]
> >>> /* as far as I understand, it's possible that p-a returns
> >>>the difference in multiples of sizeof(T), so that if element size
> >>>were 2, a[2]-a[1] would give 1 instead of 2.
> >>
> >> That's not only possible, it's /required/ for a conforming
> >> implementation to behave like this (C99 6.5.6#9): pointer
> >> subtraction always yields values in units of element size.[/color]
> >I read this, and got it like you. However, it's not my experience
> >when working with real compilers.
> >[color=darkred]
> >>>Although I never found a compiler doing this,
> >>
> >> Then you only found non-conforming compilers up until now.[/color]
> >one is gcc 2.95.3, tried on a struct with sizeof(T)==8[/color]
> <snip>
>
> Uck. IIRC gcc 2.xx is indeed broken in several ways.[/color]
[...]
I seriously doubt that gcc 2.xx, or any usable C compiler, gets
something as fundamental as pointer arithmetic wrong.
Here's a sample program:
#include <stdio.h>
int main(void)
{
double arr[10];
double *ptr5 = &(arr[5]);
double *ptr8 = &(arr[8]);
/*
* ddiff is the difference between ptr5 and ptr8, interpreted
* as pointers to double.
* cdiff is the difference bewteen ptr5 and ptr8, both interpreted
* as pointers to char.
* The subtraction operator actually yields a result of type ptrdiff_t,
* but it's implicitly converted to int; as long as it's within
* the range, no information is lost.
*/
int ddiff = ptr8 - ptr5;
int cdiff = (char*)ptr8 - (char*)ptr5;
printf("sizeof( double) = %d\n", (int)sizeof(dou ble));
printf("ptr5 = [%p]\n", (void*)ptr5);
printf("ptr8 = [%p]\n", (void*)ptr8);
printf("ddiff = %d\n", ddiff);
printf("cdiff = %d\n", cdiff);
if (cdiff == ddiff * sizeof(double)) {
printf("Looks ok\n");
}
else {
printf("Somethi ng is wrong\n");
}
return 0;
}
If it prints "Something is wrong" on your implementation, there is
indeed a serious problem. I just tried it with gcc versions 2.7.2.2,
2.8.1, 2.95.2, 3.0.4, and 3.2.2, and it printed "Looks ok" every time.
--
Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Irrwahn Grausewitz <irrwahn33@free net.de> writes:[color=blue]
> Bernhard Holzmayer <holzmayer.bern hard@deadspam.c om> wrote:[color=green]
> >Irrwahn Grausewitz wrote:
> >[color=darkred]
> >> Bernhard Holzmayer <holzmayer.bern hard@deadspam.c om> wrote:[/color][/color]
> <snip>[color=green][color=darkred]
> >>> if (p<a) return 0; /*out */
> >>
> >> If p and a didn't point into (or one past) the same array in
> >> the first place, you already invoked undefined behaviour here
> >> (C99 6.5.8#5). All bets off.[/color]
> >What a pity. Then, I guess, it's up to the caller of the function,
> >to make sure p is a valid pointer ;-)[/color]
> <snip>
>
> That's indeed the best solution. ;-)
>[color=green][color=darkred]
> >>> /* as far as I understand, it's possible that p-a returns
> >>>the difference in multiples of sizeof(T), so that if element size
> >>>were 2, a[2]-a[1] would give 1 instead of 2.
> >>
> >> That's not only possible, it's /required/ for a conforming
> >> implementation to behave like this (C99 6.5.6#9): pointer
> >> subtraction always yields values in units of element size.[/color]
> >I read this, and got it like you. However, it's not my experience
> >when working with real compilers.
> >[color=darkred]
> >>>Although I never found a compiler doing this,
> >>
> >> Then you only found non-conforming compilers up until now.[/color]
> >one is gcc 2.95.3, tried on a struct with sizeof(T)==8[/color]
> <snip>
>
> Uck. IIRC gcc 2.xx is indeed broken in several ways.[/color]
[...]
I seriously doubt that gcc 2.xx, or any usable C compiler, gets
something as fundamental as pointer arithmetic wrong.
Here's a sample program:
#include <stdio.h>
int main(void)
{
double arr[10];
double *ptr5 = &(arr[5]);
double *ptr8 = &(arr[8]);
/*
* ddiff is the difference between ptr5 and ptr8, interpreted
* as pointers to double.
* cdiff is the difference bewteen ptr5 and ptr8, both interpreted
* as pointers to char.
* The subtraction operator actually yields a result of type ptrdiff_t,
* but it's implicitly converted to int; as long as it's within
* the range, no information is lost.
*/
int ddiff = ptr8 - ptr5;
int cdiff = (char*)ptr8 - (char*)ptr5;
printf("sizeof( double) = %d\n", (int)sizeof(dou ble));
printf("ptr5 = [%p]\n", (void*)ptr5);
printf("ptr8 = [%p]\n", (void*)ptr8);
printf("ddiff = %d\n", ddiff);
printf("cdiff = %d\n", cdiff);
if (cdiff == ddiff * sizeof(double)) {
printf("Looks ok\n");
}
else {
printf("Somethi ng is wrong\n");
}
return 0;
}
If it prints "Something is wrong" on your implementation, there is
indeed a serious problem. I just tried it with gcc versions 2.7.2.2,
2.8.1, 2.95.2, 3.0.4, and 3.2.2, and it printed "Looks ok" every time.
--
Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Comment