public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Pointers in comparison expressions
@ 2005-07-12 16:24 Mirco Lorenzoni
  2005-07-12 16:32 ` Daniel Berlin
                   ` (3 more replies)
  0 siblings, 4 replies; 26+ messages in thread
From: Mirco Lorenzoni @ 2005-07-12 16:24 UTC (permalink / raw)
  To: gcc

Can a pointer appear in a C/C++ relational expression which doesn't test the 
equality (or the inequality) of that pointer with respect to another pointer? 
For example, are the comparisons in the following program legal code?

/* test.c */
#include <stdio.h>

int main(int argc, char* argv[])
{
	void *a, *b;
	int aa, bb;

	a = &aa;
	b = &bb;
	
	printf("a: %p, b: %p\n", a, b);
	if (a < b) 
		printf("a < b\n");
	else 
		printf("a >= b\n");

	if (b < a) 
		printf("b < a\n");
	else 
		printf("b >= a\n");
	return 0;
}

The execution of the compiled program produces an output like this:
a: 0xbffff55c, b: 0xbffff558
a >= b
b < a

I have compiled this program with gcc and g++, versions 3.4.4 and 4.0.1, and 
(the prehistoric) egcs 2.91.66. None of these compilers has issued any 
warning or error. I have compiled the program above whit these options: -Wall 
--ansi --pedantic .

These are the version information about the compilers: 

Reading specs from /usr/local/lib/gcc/i686-pc-linux-gnu/3.4.4/specs
Configured with: ../gcc-3.4.4/configure --srcdir=../gcc-3.4.4 
--mandir=/usr/local/share/man --infodir=/usr/local/share/info 
--enable-threads --enable-languages=c,c++,f77,java,objc --prefix=/usr/local 
--with-cpu=pentium2 --with-tune=k8 --enable-__cxa_atexit --with-x 
--enable-java-awt=gtk
Thread model: posix
gcc version 3.4.4

Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../gcc-4.0.1/configure --srcdir=../gcc-4.0.1 
--mandir=/usr/local/share/man --infodir=/usr/local/share/info 
--enable-threads --enable-languages=c,c++,f95,java,objc --prefix=/usr/local 
--with-cpu=pentium2 --with-tune=k8 --enable-__cxa_atexit --with-x 
--enable-java-awt=gtk
Thread model: posix
gcc version 4.0.1

Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/specs
gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)

I think that even if the use of relational operators other than '==' and '!=' 
is legal with pointers, the compiler should issue a warning (when the option 
-Wall is used), as it does for assignment, used as truth values, not 
surrounded with parentheses.

Thanks in advance for your reply.
Regards,
		Mirco Lorenzoni

P.S.
I'm not a list subscriber. Send me a copy of your reply, please.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
  2005-07-12 16:24 Pointers in comparison expressions Mirco Lorenzoni
@ 2005-07-12 16:32 ` Daniel Berlin
  2005-07-12 16:53   ` Dave Korn
  2005-07-12 17:03 ` chris jefferson
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 26+ messages in thread
From: Daniel Berlin @ 2005-07-12 16:32 UTC (permalink / raw)
  To: mrc.lrn; +Cc: gcc


> I think that even if the use of relational operators other than '==' and '!=' 
> is legal with pointers, the compiler should issue a warning (when the option 
> -Wall is used), as it does for assignment, used as truth values, not 
> surrounded with parentheses.

Why?
It's legal, it's useful, and used.

--Dan

^ permalink raw reply	[flat|nested] 26+ messages in thread

* RE: Pointers in comparison expressions
  2005-07-12 16:32 ` Daniel Berlin
@ 2005-07-12 16:53   ` Dave Korn
  2005-07-12 21:00     ` Andreas Schwab
  2005-07-12 21:42     ` Erik Trulsson
  0 siblings, 2 replies; 26+ messages in thread
From: Dave Korn @ 2005-07-12 16:53 UTC (permalink / raw)
  To: 'Daniel Berlin', mrc.lrn; +Cc: gcc

----Original Message----
>From: Daniel Berlin
>Sent: 12 July 2005 17:33

>> I think that even if the use of relational operators other than '==' and
>> '!=' is legal with pointers, the compiler should issue a warning (when
>> the option -Wall is used), as it does for assignment, used as truth
>> values, not surrounded with parentheses.
> 
> Why?
> It's legal, it's useful, and used.
> 
> --Dan


  Just to enlarge upon Dan's comment:

  Since pointer subtraction is well defined, and it returns an int, then ...

int *a, *b;

  if (a < b)
    dosomething ();

... is just the same as ...

int *a, *b;

  if ((b - a) >= 0)
    dosomething ();

... so do you think the compiler should warn about _all_ pointer arithmetic?

    cheers,
      DaveK
-- 
Can't think of a witty .sigline today....

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
  2005-07-12 16:24 Pointers in comparison expressions Mirco Lorenzoni
  2005-07-12 16:32 ` Daniel Berlin
@ 2005-07-12 17:03 ` chris jefferson
  2005-07-12 23:18 ` Michael Meissner
  2005-07-22 23:20 ` Geoffrey Keating
  3 siblings, 0 replies; 26+ messages in thread
From: chris jefferson @ 2005-07-12 17:03 UTC (permalink / raw)
  To: mrc.lrn; +Cc: gcc

Mirco Lorenzoni wrote:

>Can a pointer appear in a C/C++ relational expression which doesn't test the 
>equality (or the inequality) of that pointer with respect to another pointer? 
>For example, are the comparisons in the following program legal code?
>
>/* test.c */
>#include <stdio.h>
>
>int main(int argc, char* argv[])
>{
>	void *a, *b;
>	int aa, bb;
>
>	a = &aa;
>	b = &bb;
>	
>  
>
Actually I'm fairly certain at this point this program stops being legal
code, as (I believe) you can only compare pointers which are from the
same allocation (be that an array, malloc, etc).

However, comparing pointers with < is something I do all the time when
writing various kinds of algorithms. For what reason would you want to
see it warned about?

Chris

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
  2005-07-12 16:53   ` Dave Korn
@ 2005-07-12 21:00     ` Andreas Schwab
  2005-07-12 21:42     ` Erik Trulsson
  1 sibling, 0 replies; 26+ messages in thread
From: Andreas Schwab @ 2005-07-12 21:00 UTC (permalink / raw)
  To: Dave Korn; +Cc: 'Daniel Berlin', mrc.lrn, gcc

"Dave Korn" <dave.korn@artimi.com> writes:

>   Since pointer subtraction is well defined, and it returns an int, then ...
>
> int *a, *b;
>
>   if (a < b)
>     dosomething ();
>
> ... is just the same as ...
>
> int *a, *b;
>
>   if ((b - a) >= 0)
>     dosomething ();

This may not work correctly if ((char*) b - (char*) a) % sizeof int != 0
(which can happen if __alignof__ int < sizeof int).

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
  2005-07-12 16:53   ` Dave Korn
  2005-07-12 21:00     ` Andreas Schwab
@ 2005-07-12 21:42     ` Erik Trulsson
  2005-07-12 22:09       ` Joe Buck
  2005-07-16 11:49       ` Vincent Lefevre
  1 sibling, 2 replies; 26+ messages in thread
From: Erik Trulsson @ 2005-07-12 21:42 UTC (permalink / raw)
  To: Dave Korn; +Cc: 'Daniel Berlin', mrc.lrn, gcc

On Tue, Jul 12, 2005 at 05:54:00PM +0100, Dave Korn wrote:
> ----Original Message----
> >From: Daniel Berlin
> >Sent: 12 July 2005 17:33
> 
> >> I think that even if the use of relational operators other than '==' and
> >> '!=' is legal with pointers, the compiler should issue a warning (when
> >> the option -Wall is used), as it does for assignment, used as truth
> >> values, not surrounded with parentheses.
> > 
> > Why?
> > It's legal, it's useful, and used.
> > 
> > --Dan
> 
> 
>   Just to enlarge upon Dan's comment:
> 
>   Since pointer subtraction is well defined, and it returns an int, then ...
> 
> int *a, *b;
> 
>   if (a < b)
>     dosomething ();
> 
> ... is just the same as ...
> 
> int *a, *b;
> 
>   if ((b - a) >= 0)
>     dosomething ();
> 
> ... so do you think the compiler should warn about _all_ pointer arithmetic?

Pointer subtraction is only well defined if both pointers point to elements
in the same array (or one past the end of the array).  Otherwise the
behaviour is undefined.

Relational operators between pointers are only defined if both pointers
either point to elements in the same array (or one past the end of the
array), or to members of the same structure.  Otherwise the result is
undefined.


Thus, if you have code like:

  int aa,bb;
  int *a, *b;

  a=&aa;
  b=&bb;

Then expressions like "(a>b)" or "(a-b)" both have undefined behaviour,
while if you had code like

  int aa[2];
  int *a, *b;

  a=&(aa[0]);
  b=&(aa[1]);

Then the expressions "(a>b)" and "(a-b") are both well defined (and will
have the values 0 and 1 respectively.)
 

If the compiler is certain that the pointers do not point into the same
array or structure (as in my first example above) it is probably a good
idea to give a warning, but it should not warn for the legal cases (as in my
second example.)


-- 
<Insert your favourite quote here.>
Erik Trulsson
ertr1013@student.uu.se

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
  2005-07-12 21:42     ` Erik Trulsson
@ 2005-07-12 22:09       ` Joe Buck
  2005-07-12 22:28         ` Erik Trulsson
  2005-07-16 11:49       ` Vincent Lefevre
  1 sibling, 1 reply; 26+ messages in thread
From: Joe Buck @ 2005-07-12 22:09 UTC (permalink / raw)
  To: Dave Korn, 'Daniel Berlin', mrc.lrn, gcc

On Tue, Jul 12, 2005 at 11:42:23PM +0200, Erik Trulsson wrote:
> Pointer subtraction is only well defined if both pointers point to elements
> in the same array (or one past the end of the array).  Otherwise the
> behaviour is undefined.

While this is correct, there are certain cases that the standard leaves
undefined but that nevertheless can be useful; for example, pointer
subtraction can be used to estimate the amount of stack in use (of
course, it is necessary to know if the stack grows upward or downward).

Similarly, in an OS kernel, comparing pointers may make sense.

> If the compiler is certain that the pointers do not point into the same
> array or structure (as in my first example above) it is probably a good
> idea to give a warning, but it should not warn for the legal cases (as in my
> second example.)

I'd say that would be only useful in terms of a more general analysis that
implements bounds checking.  Given reliable analysis that finds suspicious
pointer comparisons, most users would be more interested in the implicit
comparison of a pointer with the boundaries of the array it corresponds
to.


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
  2005-07-12 22:09       ` Joe Buck
@ 2005-07-12 22:28         ` Erik Trulsson
  2005-07-12 22:38           ` Falk Hueffner
  2005-07-12 22:46           ` Joe Buck
  0 siblings, 2 replies; 26+ messages in thread
From: Erik Trulsson @ 2005-07-12 22:28 UTC (permalink / raw)
  To: Joe Buck; +Cc: Dave Korn, 'Daniel Berlin', mrc.lrn, gcc

On Tue, Jul 12, 2005 at 03:08:54PM -0700, Joe Buck wrote:
> On Tue, Jul 12, 2005 at 11:42:23PM +0200, Erik Trulsson wrote:
> > Pointer subtraction is only well defined if both pointers point to elements
> > in the same array (or one past the end of the array).  Otherwise the
> > behaviour is undefined.
> 
> While this is correct, there are certain cases that the standard leaves
> undefined but that nevertheless can be useful; for example, pointer
> subtraction can be used to estimate the amount of stack in use (of
> course, it is necessary to know if the stack grows upward or downward).
> 
> Similarly, in an OS kernel, comparing pointers may make sense.

Yes, there are some situations where it can be useful to compare pointers
to different objects, but then you need to make sure that the compiler you
use actually supports that.

I believe most C compilers support it in practice, but few, if any, have
actually documented it as a supported extension to C.





-- 
<Insert your favourite quote here.>
Erik Trulsson
ertr1013@student.uu.se

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
  2005-07-12 22:28         ` Erik Trulsson
@ 2005-07-12 22:38           ` Falk Hueffner
  2005-07-12 23:17             ` Joe Buck
  2005-07-12 23:27             ` Michael Meissner
  2005-07-12 22:46           ` Joe Buck
  1 sibling, 2 replies; 26+ messages in thread
From: Falk Hueffner @ 2005-07-12 22:38 UTC (permalink / raw)
  To: Joe Buck; +Cc: Dave Korn, 'Daniel Berlin', mrc.lrn, gcc

Erik Trulsson <ertr1013@student.uu.se> writes:

> On Tue, Jul 12, 2005 at 03:08:54PM -0700, Joe Buck wrote:
>> On Tue, Jul 12, 2005 at 11:42:23PM +0200, Erik Trulsson wrote:
>> > Pointer subtraction is only well defined if both pointers point to elements
>> > in the same array (or one past the end of the array).  Otherwise the
>> > behaviour is undefined.
>> 
>> While this is correct, there are certain cases that the standard leaves
>> undefined but that nevertheless can be useful; for example, pointer
>> subtraction can be used to estimate the amount of stack in use (of
>> course, it is necessary to know if the stack grows upward or downward).
>> 
>> Similarly, in an OS kernel, comparing pointers may make sense.
>
> Yes, there are some situations where it can be useful to compare pointers
> to different objects, but then you need to make sure that the compiler you
> use actually supports that.
>
> I believe most C compilers support it in practice, but few, if any, have
> actually documented it as a supported extension to C.

I don't think we should, either. People who want to do this can just
cast both pointers to size_t.

-- 
	Falk

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
  2005-07-12 22:28         ` Erik Trulsson
  2005-07-12 22:38           ` Falk Hueffner
@ 2005-07-12 22:46           ` Joe Buck
  1 sibling, 0 replies; 26+ messages in thread
From: Joe Buck @ 2005-07-12 22:46 UTC (permalink / raw)
  To: Dave Korn, 'Daniel Berlin', mrc.lrn, gcc

On Wed, Jul 13, 2005 at 12:28:47AM +0200, Erik Trulsson wrote:
> On Tue, Jul 12, 2005 at 03:08:54PM -0700, Joe Buck wrote:
> > On Tue, Jul 12, 2005 at 11:42:23PM +0200, Erik Trulsson wrote:
> > > Pointer subtraction is only well defined if both pointers point to elements
> > > in the same array (or one past the end of the array).  Otherwise the
> > > behaviour is undefined.
> > 
> > While this is correct, there are certain cases that the standard leaves
> > undefined but that nevertheless can be useful; for example, pointer
> > subtraction can be used to estimate the amount of stack in use (of
> > course, it is necessary to know if the stack grows upward or downward).
> > 
> > Similarly, in an OS kernel, comparing pointers may make sense.
> 
> Yes, there are some situations where it can be useful to compare pointers
> to different objects, but then you need to make sure that the compiler you
> use actually supports that.

No, you don't need to check.  You are confusing standards legalese with
industrial practice.  You are currently running a computer that depends
on such code (whether you run Unix, Linux, BSD, or Windows).

In any case, the C standard together with the portable ABI standard that
gcc and compatible compilers conform to suffice to guarantee that you can
write code that will compare arbitrary pointers safely.  Such code is, of
course, non-portable, which means that it needs to be tested with each
compiler and OS used.

The only compilers where there is an issue with pointer comparison are the
various memory models for 16-bit segmented architectures (e.g. 16-bit
Windows), and even those compilers provide "huge pointers" because
sometimes it is necessary to compare pointers beyond the guarantees made
by the C standard.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
  2005-07-12 22:38           ` Falk Hueffner
@ 2005-07-12 23:17             ` Joe Buck
  2005-07-12 23:28               ` Falk Hueffner
  2005-07-12 23:27             ` Michael Meissner
  1 sibling, 1 reply; 26+ messages in thread
From: Joe Buck @ 2005-07-12 23:17 UTC (permalink / raw)
  To: Falk Hueffner; +Cc: Dave Korn, 'Daniel Berlin', mrc.lrn, gcc

On Wed, Jul 13, 2005 at 12:38:11AM +0200, Falk Hueffner wrote:
> Erik Trulsson <ertr1013@student.uu.se> writes:
> > I believe most C compilers support it in practice, but few, if any, have
> > actually documented it as a supported extension to C.
> 
> I don't think we should, either. People who want to do this can just
> cast both pointers to size_t.

If you want to be pedantic, that's not portable; in particular, it will
break for some of the memory models used with 16-bit Windows (if you never
had to program those, thank your favorite deity).  The reason is that, in
those modes, different objects can be in different segments, but pointers
are only 16 bit.  Casting them to size_t won't make them compare correctly
or reliably.  But for the kind of uses I was describing, that's not a
problem: you first cast the pointers into "huge pointers", which are 32
bit, and those huge pointers can be compared reliably.  (Complicating the
picture were "far pointers", which might be equal but not compare equal if
there are overlapping segments).

The conclusion is that a direct pointer comparison is just as good as
casting to size_t first.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
  2005-07-12 16:24 Pointers in comparison expressions Mirco Lorenzoni
  2005-07-12 16:32 ` Daniel Berlin
  2005-07-12 17:03 ` chris jefferson
@ 2005-07-12 23:18 ` Michael Meissner
  2005-07-22 23:20 ` Geoffrey Keating
  3 siblings, 0 replies; 26+ messages in thread
From: Michael Meissner @ 2005-07-12 23:18 UTC (permalink / raw)
  To: gcc; +Cc: mrc.lrn

On Tue, Jul 12, 2005 at 06:25:45PM +0200, Mirco Lorenzoni wrote:
> Can a pointer appear in a C/C++ relational expression which doesn't test the 
> equality (or the inequality) of that pointer with respect to another pointer? 
> For example, are the comparisons in the following program legal code?
> 
> /* test.c */
> #include <stdio.h>
> 
> int main(int argc, char* argv[])
> {
> 	void *a, *b;
> 	int aa, bb;
> 
> 	a = &aa;
> 	b = &bb;
> 	
> 	printf("a: %p, b: %p\n", a, b);
> 	if (a < b) 
> 		printf("a < b\n");
> 	else 
> 		printf("a >= b\n");
> 
> 	if (b < a) 
> 		printf("b < a\n");
> 	else 
> 		printf("b >= a\n");
> 	return 0;
> }

No, this is not legal.  Relational tests between pointers is only allowed by
the ISO C standard if the two pointers point into the same array, or if a
pointer points to exactly one byte beyond the array.
> 
> P.S.
> I'm not a list subscriber. Send me a copy of your reply, please.

Ummm, I don't understand how you expect to get replies if you don't monitor the
list.

-- 
Michael Meissner
email: gnu@the-meissners.org
http://www.the-meissners.org

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
  2005-07-12 22:38           ` Falk Hueffner
  2005-07-12 23:17             ` Joe Buck
@ 2005-07-12 23:27             ` Michael Meissner
  1 sibling, 0 replies; 26+ messages in thread
From: Michael Meissner @ 2005-07-12 23:27 UTC (permalink / raw)
  To: gcc

On Wed, Jul 13, 2005 at 12:38:11AM +0200, Falk Hueffner wrote:
> Erik Trulsson <ertr1013@student.uu.se> writes:
> 
> > On Tue, Jul 12, 2005 at 03:08:54PM -0700, Joe Buck wrote:
> >> On Tue, Jul 12, 2005 at 11:42:23PM +0200, Erik Trulsson wrote:
> >> > Pointer subtraction is only well defined if both pointers point to elements
> >> > in the same array (or one past the end of the array).  Otherwise the
> >> > behaviour is undefined.
> >> 
> >> While this is correct, there are certain cases that the standard leaves
> >> undefined but that nevertheless can be useful; for example, pointer
> >> subtraction can be used to estimate the amount of stack in use (of
> >> course, it is necessary to know if the stack grows upward or downward).
> >> 
> >> Similarly, in an OS kernel, comparing pointers may make sense.
> >
> > Yes, there are some situations where it can be useful to compare pointers
> > to different objects, but then you need to make sure that the compiler you
> > use actually supports that.
> >
> > I believe most C compilers support it in practice, but few, if any, have
> > actually documented it as a supported extension to C.
> 
> I don't think we should, either. People who want to do this can just
> cast both pointers to size_t.

Note, it is not guaranteed that size_t is big enough to hold a pointer.  In
particular, cast your minds back to when we had 16 and 32-bit x86 code, and
some compilers had different memory models like near/far (which was the case
when the C90 standard was defined).  Size_t could be 16-bits, since the
compiler would not allow any item bigger than 32K to be created, but pointers
could have the segment pointer as well as the bottom 16-bits.  If a compiler
knew size_t was restricted to 16 bits, it could eliminate code to normalize the
pointer before doing the comparison, and just do a simple subtraction.

-- 
Michael Meissner
email: gnu@the-meissners.org
http://www.the-meissners.org

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
  2005-07-12 23:17             ` Joe Buck
@ 2005-07-12 23:28               ` Falk Hueffner
  2005-07-13  2:02                 ` Joe Buck
  2005-07-13 21:42                 ` Olivier Galibert
  0 siblings, 2 replies; 26+ messages in thread
From: Falk Hueffner @ 2005-07-12 23:28 UTC (permalink / raw)
  To: Joe Buck; +Cc: Dave Korn, 'Daniel Berlin', mrc.lrn, gcc

Joe Buck <Joe.Buck@synopsys.COM> writes:

> On Wed, Jul 13, 2005 at 12:38:11AM +0200, Falk Hueffner wrote:
>> Erik Trulsson <ertr1013@student.uu.se> writes:
>> > I believe most C compilers support it in practice, but few, if any, have
>> > actually documented it as a supported extension to C.
>> 
>> I don't think we should, either. People who want to do this can just
>> cast both pointers to size_t.
>
> If you want to be pedantic, that's not portable; in particular, it
> will break for some of the memory models used with 16-bit Windows

You're missing my point; size_t was just an example, whoever does this
will know what the correct type is for their system.  All I'm saying
is that we shouldn't go to the trouble to document and kick along some
language extension, maybe even miss some optimization because of it,
when there's a perfectly fine alternative to it for the user.

-- 
	Falk

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
  2005-07-12 23:28               ` Falk Hueffner
@ 2005-07-13  2:02                 ` Joe Buck
  2005-07-13 21:42                 ` Olivier Galibert
  1 sibling, 0 replies; 26+ messages in thread
From: Joe Buck @ 2005-07-13  2:02 UTC (permalink / raw)
  To: Falk Hueffner; +Cc: gcc

On Wed, Jul 13, 2005 at 01:28:14AM +0200, Falk Hueffner wrote:
> Joe Buck <Joe.Buck@synopsys.COM> writes:
> > If you want to be pedantic, that's not portable; in particular, it
> > will break for some of the memory models used with 16-bit Windows
> 
> You're missing my point; size_t was just an example, whoever does this
> will know what the correct type is for their system.

I'm afraid that my grey hairs give me an advantage here.

You're missing my point; *there is no correct size*!

In segmented memory models, the pointers are only offsets in the current
segment; casting them to any integer type you choose simply will not work.

Casting to size_t (or any other integral type large enough to hold the
pointer) never gives any advantage over comparing the pointers directly.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
  2005-07-12 23:28               ` Falk Hueffner
  2005-07-13  2:02                 ` Joe Buck
@ 2005-07-13 21:42                 ` Olivier Galibert
  1 sibling, 0 replies; 26+ messages in thread
From: Olivier Galibert @ 2005-07-13 21:42 UTC (permalink / raw)
  To: Falk Hueffner; +Cc: Joe Buck, Dave Korn, 'Daniel Berlin', mrc.lrn, gcc

On Wed, Jul 13, 2005 at 01:28:14AM +0200, Falk Hueffner wrote:
> You're missing my point; size_t was just an example, whoever does this
> will know what the correct type is for their system.  All I'm saying
> is that we shouldn't go to the trouble to document and kick along some
> language extension, maybe even miss some optimization because of it,
> when there's a perfectly fine alternative to it for the user.

Having the user add stupid, potentially breakable casts which decrease
readability just because the standard says the compiler is allowed to
be a prick is not necessarily a good idea.  I don't really see the
point of breaking or even warning on pretty much every memory
management or garbage collection code out there.

  OG.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
  2005-07-12 21:42     ` Erik Trulsson
  2005-07-12 22:09       ` Joe Buck
@ 2005-07-16 11:49       ` Vincent Lefevre
  2005-07-17 16:55         ` Paul Koning
  1 sibling, 1 reply; 26+ messages in thread
From: Vincent Lefevre @ 2005-07-16 11:49 UTC (permalink / raw)
  To: gcc; +Cc: Dave Korn, 'Daniel Berlin', mrc.lrn

On 2005-07-12 23:42:23 +0200, Erik Trulsson wrote:
> Pointer subtraction is only well defined if both pointers point to
> elements in the same array (or one past the end of the array).

I don't know what you mean by "well defined", but even in this case,
the behavior can be undefined. So, replacing a < b by a - b < 0 is not
guaranteed to work with every implementation, just like with integers.

-- 
Vincent Lefèvre <vincent@vinc17.org> - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / SPACES project at LORIA

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
  2005-07-16 11:49       ` Vincent Lefevre
@ 2005-07-17 16:55         ` Paul Koning
  2005-07-18  1:49           ` Vincent Lefevre
  0 siblings, 1 reply; 26+ messages in thread
From: Paul Koning @ 2005-07-17 16:55 UTC (permalink / raw)
  To: vincent+gcc; +Cc: gcc, dave.korn, dberlin, mrc.lrn

>>>>> "Vincent" == Vincent Lefevre <vincent+gcc@vinc17.org> writes:

 Vincent> On 2005-07-12 23:42:23 +0200, Erik Trulsson wrote:
 >> Pointer subtraction is only well defined if both pointers point to
 >> elements in the same array (or one past the end of the array).

 Vincent> I don't know what you mean by "well defined", but even in
 Vincent> this case, the behavior can be undefined. So, replacing a <
 Vincent> b by a - b < 0 is not guaranteed to work with every
 Vincent> implementation, just like with integers.

Are you sayinvg that a-b is not always "guaranteed to work" when a and
b point to elements of the same array?  That sounds wrong; can you
given an example or standards text that supports this?

      paul

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
  2005-07-17 16:55         ` Paul Koning
@ 2005-07-18  1:49           ` Vincent Lefevre
  2005-07-18  3:13             ` D. Hugh Redelmeier
  2005-07-18 13:09             ` Paul Koning
  0 siblings, 2 replies; 26+ messages in thread
From: Vincent Lefevre @ 2005-07-18  1:49 UTC (permalink / raw)
  To: gcc

On 2005-07-17 12:55:38 -0400, Paul Koning wrote:
> Are you sayinvg that a-b is not always "guaranteed to work" when a
> and b point to elements of the same array? That sounds wrong; can
> you given an example or standards text that supports this?

       6.5.6  Additive operators
[...]
       [#9]  When  two pointers are subtracted, both shall point to
       elements of the same array object,  or  one  past  the  last
       element of the array object; the result is the difference of
       the subscripts of the two array elements.  The size  of  the
       result  is  implementation-defined,  and  its type (a signed
       integer type) is ptrdiff_t defined in the <stddef.h> header.
       If  the  result  is  not  representable in an object of that
       type, the behavior is undefined.  In  other  words,  if  the
       expressions  P and Q point to, respectively, the i-th and j-
       th elements of an array object, the expression  (P)-(Q)  has
       the  value  i-j provided the value fits in an object of type
       ptrdiff_t.  [...]

See the sentence "If the result..." and the last few words of the
next sentence.

-- 
Vincent Lefèvre <vincent@vinc17.org> - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / SPACES project at LORIA

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
  2005-07-18  1:49           ` Vincent Lefevre
@ 2005-07-18  3:13             ` D. Hugh Redelmeier
  2005-07-18 13:13               ` Paul Koning
  2005-07-18 13:09             ` Paul Koning
  1 sibling, 1 reply; 26+ messages in thread
From: D. Hugh Redelmeier @ 2005-07-18  3:13 UTC (permalink / raw)
  To: Vincent Lefevre; +Cc: gcc

| From: Vincent Lefevre <vincent+gcc@vinc17.org>
| To: gcc@gcc.gnu.org
| Subject: Re: Pointers in comparison expressions
| 
| On 2005-07-17 12:55:38 -0400, Paul Koning wrote:
| > Are you sayinvg that a-b is not always "guaranteed to work" when a
| > and b point to elements of the same array? That sounds wrong; can
| > you given an example or standards text that supports this?
| 
|        6.5.6  Additive operators
| [...]
|        [#9]  When  two pointers are subtracted, both shall point to
|        elements of the same array object,  or  one  past  the  last
|        element of the array object; the result is the difference of
|        the subscripts of the two array elements.  The size  of  the
|        result  is  implementation-defined,  and  its type (a signed
|        integer type) is ptrdiff_t defined in the <stddef.h> header.
|        If  the  result  is  not  representable in an object of that
|        type, the behavior is undefined.  In  other  words,  if  the
|        expressions  P and Q point to, respectively, the i-th and j-
|        th elements of an array object, the expression  (P)-(Q)  has
|        the  value  i-j provided the value fits in an object of type
|        ptrdiff_t.  [...]
| 
| See the sentence "If the result..." and the last few words of the
| next sentence.

This is true.  And an abomination.  But I will explain a bit more
where this came from.

On, for example, the PDP-11, size_t would be unsigned int (16 bits).
ptrdiff_t would be signed int because making it long feels wrong -- it
is too expensive and would only be more correct in an extremely rare
case.  That case can only come up when dealing with a char array
larger than 32K.  Since the maximum addressable data space was 64K, no
real program would do this (except to make fools of us).

So the committee felt that it was important to allow ptrdiff_t to be
"too small".  I suggested that ptrdiff_t should be required to be at
least as large as the signed variant of size_t, but they did not
accept this.  So a legal implementation may make ptrdiff_t as small as
signed char (recent versions of the standard mandate that PTRDIFF_MAX
must be at least 64K-1; this negates the original reason for the
laxity).

This same logic can now be transferred to 32-bit machines.  ptrdiff_t
on most 32-bit machines is 32 bits, so a char array larger than 2G
could allow for overflowing pointer subtraction.

Since GCC knows the range of values that can be represented in
ptrdiff_t, it knows whether the subtraction might overflow.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
  2005-07-18  1:49           ` Vincent Lefevre
  2005-07-18  3:13             ` D. Hugh Redelmeier
@ 2005-07-18 13:09             ` Paul Koning
  1 sibling, 0 replies; 26+ messages in thread
From: Paul Koning @ 2005-07-18 13:09 UTC (permalink / raw)
  To: vincent+gcc; +Cc: gcc

>>>>> "Vincent" == Vincent Lefevre <vincent+gcc@vinc17.org> writes:

 Vincent> On 2005-07-17 12:55:38 -0400, Paul Koning wrote:
 >> Are you sayinvg that a-b is not always "guaranteed to work" when a
 >> and b point to elements of the same array? That sounds wrong; can
 >> you given an example or standards text that supports this?

 Vincent> 6.5.6 Additive operators [...]  [#9] When two pointers are
 Vincent> subtracted, both shall point to elements of the same array
 Vincent> object, or one past the last element of the array object;
 Vincent> the result is the difference of the subscripts of the two
 Vincent> array elements.  The size of the result is
 Vincent> implementation-defined, and its type (a signed integer type)
 Vincent> is ptrdiff_t defined in the <stddef.h> header.  If the
 Vincent> result is not representable in an object of that type, the
 Vincent> behavior is undefined.  In other words, if the expressions P
 Vincent> and Q point to, respectively, the i-th and j- th elements of
 Vincent> an array object, the expression (P)-(Q) has the value i-j
 Vincent> provided the value fits in an object of type ptrdiff_t.
 Vincent> [...]

 Vincent> See the sentence "If the result..." and the last few words
 Vincent> of the next sentence.

Bizarre.  Is there a real world example where this is done?  I can't
imagine any place where this exception is justified.

	paul

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
  2005-07-18  3:13             ` D. Hugh Redelmeier
@ 2005-07-18 13:13               ` Paul Koning
  0 siblings, 0 replies; 26+ messages in thread
From: Paul Koning @ 2005-07-18 13:13 UTC (permalink / raw)
  To: hugh; +Cc: gcc

>>>>> "D" == D Hugh Redelmeier <hugh@mimosa.com> writes:

 D> This is true.  And an abomination.  But I will explain a bit more
 D> where this came from. ...

Thanks Doug.

"Abomination" is a good word for it.

      paul

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
  2005-07-12 16:24 Pointers in comparison expressions Mirco Lorenzoni
                   ` (2 preceding siblings ...)
  2005-07-12 23:18 ` Michael Meissner
@ 2005-07-22 23:20 ` Geoffrey Keating
  3 siblings, 0 replies; 26+ messages in thread
From: Geoffrey Keating @ 2005-07-22 23:20 UTC (permalink / raw)
  To: mrc.lrn; +Cc: gcc

Mirco Lorenzoni <mrc.lrn@inwind.it> writes:

> Can a pointer appear in a C/C++ relational expression which doesn't test the 
> equality (or the inequality) of that pointer with respect to another pointer?

Yes.

> For example, are the comparisons in the following program legal code?

No.

> /* test.c */
> #include <stdio.h>
> 
> int main(int argc, char* argv[])
> {
> 	void *a, *b;
> 	int aa, bb;
> 
> 	a = &aa;
> 	b = &bb;
> 	
> 	printf("a: %p, b: %p\n", a, b);
> 	if (a < b) 

Because 'a' and 'b' are not part of the same array, the behaviour is
undefined.

However, you can say

char a[100];

if (a + 3 >= a + 6)
  abort ();

which has defined behaviour (does not call abort()).

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
  2005-07-24  1:13 Paul Schlie
@ 2005-07-26  4:43 ` Geoff Keating
  0 siblings, 0 replies; 26+ messages in thread
From: Geoff Keating @ 2005-07-26  4:43 UTC (permalink / raw)
  To: Paul Schlie; +Cc: mrc.lrn, gcc

[-- Attachment #1: Type: text/plain, Size: 1654 bytes --]


On 23/07/2005, at 6:12 PM, Paul Schlie wrote:

>> Geoffrey Keating wrote:
>>
>>> Mirco Lorenzon wrote:
>>>
>>> .., are comparisons in the following program legal code?
>>>
>>
>> No.
>>
>>
>>> ...
>>> void *a, *b;
>>> ...
>>> if (a < b)
>>>
>>
>> Because 'a' and 'b' are not part of the same array,
>> the behaviour is undefined.
>>
>
> Although I don't mean to contest the conclusion, I do find it  
> curious that
> as all pointer values referencing unique objects must be  
> correspondingly
> unique, it would follow that they will be correspondingly ordered with
> respect to each other.  Therefore although technically undefined,  
> it seems
> quite reasonable to expect an implementation to support ordered  
> inequality
> comparisons between arbitrary pointers to equivalent effective types?

Consider an implementation which does garbage collection and  
compaction.  In such an implementation, it might be quite  
inconvenient to have to maintain a consistent ordering for all pointers.

> As it would seem otherwise impossible for an implementation to  
> support the
> ability to write code which enables the relative comparison of  
> generalized
> memory pointers unless one were to explicitly declare a union of an  
> array
> of all potentially allocateable memory, and all explicitly and  
> implicitly
> declared objects; which doesn't seem reasonable?

Although the C language doesn't guarantee the availability of such  
support, there is nothing that prevents an implementation from saying  
that it supports it, and in fact GCC does say that it supports it,  
through the use of a construct like

((intptr_t) a) < ((intptr_t) b)


[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 2410 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
@ 2005-07-24  1:13 Paul Schlie
  2005-07-26  4:43 ` Geoff Keating
  0 siblings, 1 reply; 26+ messages in thread
From: Paul Schlie @ 2005-07-24  1:13 UTC (permalink / raw)
  To: Geoffrey Keating; +Cc: mrc.lrn, gcc

> Geoffrey Keating wrote:
>> Mirco Lorenzon wrote:
>>
>> .., are comparisons in the following program legal code?
>
> No.
>
>> ...
>> void *a, *b;
>> ...
>> if (a < b) 
>
> Because 'a' and 'b' are not part of the same array,
> the behaviour is undefined.

Although I don't mean to contest the conclusion, I do find it curious that
as all pointer values referencing unique objects must be correspondingly
unique, it would follow that they will be correspondingly ordered with
respect to each other.  Therefore although technically undefined, it seems
quite reasonable to expect an implementation to support ordered inequality
comparisons between arbitrary pointers to equivalent effective types?

As it would seem otherwise impossible for an implementation to support the
ability to write code which enables the relative comparison of generalized
memory pointers unless one were to explicitly declare a union of an array
of all potentially allocateable memory, and all explicitly and implicitly
declared objects; which doesn't seem reasonable?




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Pointers in comparison expressions
@ 2005-07-13 13:53 Morten Welinder
  0 siblings, 0 replies; 26+ messages in thread
From: Morten Welinder @ 2005-07-13 13:53 UTC (permalink / raw)
  To: gcc

> Relational tests between pointers is only allowed by
> the ISO C standard if the two pointers point into the
> same array, or if a pointer points to exactly one byte
> beyond the array.

There actually is a way to compare arbitrary data pointers
within the C standards: you send the pointers through a printf-
type function using "%p" and strcmp the results.  That'll give
you some kind of ordering, though not necessarily the obvious
one.

(No, I am not serously suggesting that anyone in their right mind
you actually do so.  Why does this keyboard have a smiley key?)

Note, btw., that such use of %p also rules out using a garbage
collector for C and C++.  It simply cannot work if some of your
pointers have been sent off by email to the other end of the
world.  At the very least you would have to consider any pointer
that made it through %p to be live forever.

Morten

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2005-07-26  4:43 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-07-12 16:24 Pointers in comparison expressions Mirco Lorenzoni
2005-07-12 16:32 ` Daniel Berlin
2005-07-12 16:53   ` Dave Korn
2005-07-12 21:00     ` Andreas Schwab
2005-07-12 21:42     ` Erik Trulsson
2005-07-12 22:09       ` Joe Buck
2005-07-12 22:28         ` Erik Trulsson
2005-07-12 22:38           ` Falk Hueffner
2005-07-12 23:17             ` Joe Buck
2005-07-12 23:28               ` Falk Hueffner
2005-07-13  2:02                 ` Joe Buck
2005-07-13 21:42                 ` Olivier Galibert
2005-07-12 23:27             ` Michael Meissner
2005-07-12 22:46           ` Joe Buck
2005-07-16 11:49       ` Vincent Lefevre
2005-07-17 16:55         ` Paul Koning
2005-07-18  1:49           ` Vincent Lefevre
2005-07-18  3:13             ` D. Hugh Redelmeier
2005-07-18 13:13               ` Paul Koning
2005-07-18 13:09             ` Paul Koning
2005-07-12 17:03 ` chris jefferson
2005-07-12 23:18 ` Michael Meissner
2005-07-22 23:20 ` Geoffrey Keating
2005-07-13 13:53 Morten Welinder
2005-07-24  1:13 Paul Schlie
2005-07-26  4:43 ` Geoff Keating

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).