473,287 Members | 1,413 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,287 software developers and data experts.

Comparing pointers

In C you can compare two pointers, p<q, as long as they come from the
same array or the same malloc()ated block. Otherwise you can't.

What I'd like to do is write a function
int comparable(void *p, void *q)
that will take any two pointers and decide whether they can be compared
or not.

I really can't think how to do this - any suggestions?

JC.

Jun 5 '07 #1
25 12955
On Tue, 05 Jun 2007 23:44:57 +0200, J Caesar wrote:
In C you can compare two pointers, p<q, as long as they come from the
same array or the same malloc()ated block. Otherwise you can't.
Really!? How have I managed to do so all these years?

Pointers are just addresses - usually 32-, these days more and
more, 64-bit unsigned integers. Which you can always compare at will.
Usually you'll want for them to be pointers to the same type of data, of
course.

>
What I'd like to do is write a function int comparable(void *p, void *q)
that will take any two pointers and decide whether they can be compared
or not.

I really can't think how to do this - any suggestions?

JC.
Jun 5 '07 #2

"J Caesar" <in*****@nospam.comwrote in message
news:sl********************@nospam.com...
In C you can compare two pointers, p<q, as long as they come from the
same array or the same malloc()ated block. Otherwise you can't.

What I'd like to do is write a function
int comparable(void *p, void *q)
that will take any two pointers and decide whether they can be compared
or not.

I really can't think how to do this - any suggestions?
It can't be done. Or rather, it can't be done portably. To do it
non-portably is probably either trivial or the compiler has no issues with
pointers to different blocks.

The "no comparison" rule is a kludge to allow for funny architectures. It
becomes a nuisance when you need to know whether a pointer comes from a
certain block or not. However you don't need that information very
frequently, and on balance it is probably better to make the compiler easier
to implement or code to run faster.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Jun 5 '07 #3

"Ivar Rosquist" <IR*******@irq.orgwrote in message
news:pa*********************@irq.org...
On Tue, 05 Jun 2007 23:44:57 +0200, J Caesar wrote:
>In C you can compare two pointers, p<q, as long as they come from the
same array or the same malloc()ated block. Otherwise you can't.

Really!? How have I managed to do so all these years?
It is undefined behaviour. Realistically a flat memory architecture is just
going to do a starightforwards subtraction of bits. However it could trap or
return funny results on some machines.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Jun 5 '07 #4
In article <sl********************@nospam.com>,
J Caesar <in*****@nospam.comwrote:
>In C you can compare two pointers, p<q, as long as they come from the
same array or the same malloc()ated block. Otherwise you can't.

What I'd like to do is write a function
int comparable(void *p, void *q)
that will take any two pointers and decide whether they can be compared
or not.

I really can't think how to do this - any suggestions?
You're right, you can't. But why do you want to? What are you trying
to achieve?

Note that you can compare pointers for equality even if they are
from different objects.

-- Richard

--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Jun 5 '07 #5
In article <pa*********************@irq.org>,
Ivar Rosquist <IR*******@irq.orgwrote:
>On Tue, 05 Jun 2007 23:44:57 +0200, J Caesar wrote:
>In C you can compare two pointers, p<q, as long as they come from the
same array or the same malloc()ated block. Otherwise you can't.
> Really!? How have I managed to do so all these years?
Non-portably.
> Pointers are just addresses - usually 32-, these days more and
more, 64-bit unsigned integers. Which you can always compare at will.
Usually you'll want for them to be pointers to the same type of data, of
course.
Pointers are not necessarily just addresses: pointers may be opaque
with storage silently managed "under the hood", or pointers may
include type information, or pointers may include not have the
address information in numeric order (e.g., Cray put the character
offset bits in the upper byte). Or, as was common on VMS, pointers
might be the address of "descriptors" -- a block of data that
describes the type and array and virtual memory address of the
actual storage. And when you are working with a Harvard architecture,
a pointer to a function could have exactly the same numeric value
as a pointer to an object: since C does not provide any operations
that translate between function pointers and object pointers, there
is no conflict in having a function pointer with the same value
as an object pointer, with the code knowing which kind of instructions
are needed for the correct kind of access.
--
All is vanity. -- Ecclesiastes
Jun 5 '07 #6
On 5 Jun 2007 at 22:12, Richard Tobin wrote:
You're right, you can't. But why do you want to? What are you trying
to achieve?

Note that you can compare pointers for equality even if they are
from different objects.
This gives one method: write a wrapper to malloc to store a pointer to
each block allocated together with the size of the block. Then do an
exhaustive search over all pointers to all elements of all blocks
allocated to find which blocks p and q are in (only needs you to compare
each pointer for equality with p or q, which is legal). And you're done.

I see two problems: 1) very inefficient if large tracts of memory are
allocated; 2) fails if p or q point inside statically allocated arrays
rather than malloc()ed blocks.

JC.
-- Richard
Jun 5 '07 #7
On Jun 5, 11:02 pm, Ivar Rosquist <IRosqu...@irq.orgwrote:
On Tue, 05 Jun 2007 23:44:57 +0200, J Caesar wrote:
In C you can compare two pointers, p<q, as long as they come from the
same array or the same malloc()ated block. Otherwise you can't.

Really!? How have I managed to do so all these years?
By ignoring the C Standard and by avoiding any C implementations with
segmented memory.

Jun 5 '07 #8
In article <11**********************@p47g2000hsd.googlegroups .com>,
christian.bau <ch***********@cbau.wanadoo.co.ukwrote:
In C you can compare two pointers, p<q, as long as they come from the
same array or the same malloc()ated block. Otherwise you can't.
> Really!? How have I managed to do so all these years?
>By ignoring the C Standard and by avoiding any C implementations with
segmented memory.
Which shows poor judgment but good taste.

-- Richard

--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Jun 5 '07 #9
J Caesar wrote, On 05/06/07 22:44:
In C you can compare two pointers, p<q, as long as they come from the
same array or the same malloc()ated block. Otherwise you can't.

What I'd like to do is write a function
int comparable(void *p, void *q)
that will take any two pointers and decide whether they can be compared
or not.

I really can't think how to do this - any suggestions?
Your initial thought is correct, you can't do the check in standard C.
--
Flash Gordon
Jun 5 '07 #10
J Caesar <in*****@nospam.comwrites:
In C you can compare two pointers, p<q, as long as they come from the
same array or the same malloc()ated block. Otherwise you can't.

What I'd like to do is write a function
int comparable(void *p, void *q)
that will take any two pointers and decide whether they can be compared
or not.

I really can't think how to do this - any suggestions?
I don't believe there's any way to do this in standard C. Attempting
to compare the pointers invokes undefined behavior; there's no way to
detect that before running into it.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 5 '07 #11
christian.bau wrote:
On Jun 5, 11:02 pm, Ivar Rosquist <IRosqu...@irq.orgwrote:
>On Tue, 05 Jun 2007 23:44:57 +0200, J Caesar wrote:
>>In C you can compare two pointers, p<q, as long as they come from the
same array or the same malloc()ated block. Otherwise you can't.
Really!? How have I managed to do so all these years?

By ignoring the C Standard and by avoiding any C implementations with
segmented memory.
Segmented or virtual memory.

--
Ian Collins.
Jun 6 '07 #12
J Caesar wrote:
On 5 Jun 2007 at 22:12, Richard Tobin wrote:
>You're right, you can't. But why do you want to? What are you
trying to achieve?

Note that you can compare pointers for equality even if they
are from different objects.

This gives one method: write a wrapper to malloc to store a
pointer to each block allocated together with the size of the
block. Then do an exhaustive search over all pointers to all
elements of all blocks allocated to find which blocks p and q
are in (only needs you to compare each pointer for equality with
p or q, which is legal). And you're done.

I see two problems: 1) very inefficient if large tracts of memory
are allocated; 2) fails if p or q point inside statically
allocated arrays rather than malloc()ed blocks.
Arrays etc. can also be allocated locally and non-static.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
<http://kadaitcha.cx/vista/dogsbreakfast/index.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Jun 6 '07 #13
On Jun 6, 2:44 am, J Caesar <inva...@nospam.comwrote:
In C you can compare two pointers, p<q, as long as they come from the
same array or the same malloc()ated block. Otherwise you can't.

What I'd like to do is write a function
int comparable(void *p, void *q)
that will take any two pointers and decide whether they can be compared
or not.

I really can't think how to do this - any suggestions?

JC.
Typecast the pointers to 'unsigned int' before comparing them.
Thanks, Regards,
Vinoj

Jun 6 '07 #14
Vinoj wrote:
On Jun 6, 2:44 am, J Caesar <inva...@nospam.comwrote:
>In C you can compare two pointers, p<q, as long as they come from the
same array or the same malloc()ated block. Otherwise you can't.

What I'd like to do is write a function
int comparable(void *p, void *q)
that will take any two pointers and decide whether they can be compared
or not.

I really can't think how to do this - any suggestions?

Typecast the pointers to 'unsigned int' before comparing them.
Cast, not typecast. This is bad advice for at least three reasons:

Appropriate pointers can be compared without any casts.

On many systems, including the one I'm typing this on, pointers are
larger than unsigned int.

Casting hides the intent.

--
Ian Collins.
Jun 6 '07 #15
On Jun 6, 1:42 pm, Ian Collins <ian-n...@hotmail.comwrote:
Vinoj wrote:
On Jun 6, 2:44 am, J Caesar <inva...@nospam.comwrote:
In C you can compare two pointers, p<q, as long as they come from the
same array or the same malloc()ated block. Otherwise you can't.
What I'd like to do is write a function
int comparable(void *p, void *q)
that will take any two pointers and decide whether they can be compared
or not.
I really can't think how to do this - any suggestions?
Typecast the pointers to 'unsigned int' before comparing them.

Cast, not typecast. This is bad advice for at least three reasons:

Appropriate pointers can be compared without any casts.

On many systems, including the one I'm typing this on, pointers are
larger than unsigned int.

Casting hides the intent.

--
Ian Collins.
I am yet to buy a 64-bit system. Due to the lack of OS support I am
unable to buy one. I just want to run Linux on a 64-bit system. Can
you please provide me a pointer, where I can readily get IA-64 Linux
Distributable. It seems there is no support for DOS in 64 bit OS, so
I cannot get a DOS box on Windows if I have a Dual Boot? I just dont
want to go for a expensive server models that take up my room space
where I already I have 2 machines one Pentium 4 HT and one Celeron,
for device driver WinDBG and such stuff.

Thanks, Regards,
Vinoj

Jun 6 '07 #16
Vinoj said:
On Jun 6, 2:44 am, J Caesar <inva...@nospam.comwrote:
>In C you can compare two pointers, p<q, as long as they come from the
same array or the same malloc()ated block. Otherwise you can't.

What I'd like to do is write a function
int comparable(void *p, void *q)
that will take any two pointers and decide whether they can be
compared or not.

I really can't think how to do this - any suggestions?

JC.

Typecast the pointers to 'unsigned int' before comparing them.
Presuming you mean "cast", how would that help to establish whether they
can be compared /without/ the cast? And if your purpose is to avoid the
question altogether by making sure they can *always* be compared,
consider the possibility that the cast loses information - for example,
imagine a system with 16-bit unsigned ints and 20-bit pointers. (No,
that wasn't an accidental choice.)

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Jun 6 '07 #17
Ian Collins wrote:
>
Vinoj wrote:
On Jun 6, 2:44 am, J Caesar <inva...@nospam.comwrote:
In C you can compare two pointers, p<q, as long as they come from the
same array or the same malloc()ated block. Otherwise you can't.

What I'd like to do is write a function
int comparable(void *p, void *q)
that will take any two pointers and decide whether they can be compared
or not.

I really can't think how to do this - any suggestions?
Typecast the pointers to 'unsigned int' before comparing them.
Cast, not typecast. This is bad advice for at least three reasons:

Appropriate pointers can be compared without any casts.

On many systems, including the one I'm typing this on, pointers are
larger than unsigned int.

Casting hides the intent.
#4 The result of the comparison of the resulting 'unsigned int'
values, doesn't imply which pointer has the higher address.

--
pete
Jun 6 '07 #18
Vinoj wrote:
On Jun 6, 2:44 am, J Caesar <inva...@nospam.comwrote:
>In C you can compare two pointers, p<q, as long as they come from
the same array or the same malloc()ated block. Otherwise you can't.

What I'd like to do is write a function
int comparable(void *p, void *q)
that will take any two pointers and decide whether they can be
compared or not.

I really can't think how to do this - any suggestions?

Typecast the pointers to 'unsigned int' before comparing them.
Better to avoid casts (which are usually errors). i.e., use:

int comparable(void *p, void *q) {
T pp = p; qp = q;

/* now work with pp and qp, which
point to the appropriate types */
...
}

The decision is not up to you, but depends on the system details.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
<http://kadaitcha.cx/vista/dogsbreakfast/index.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Jun 6 '07 #19
Vinoj <vi***********@gmail.comwrites:
[...]
I am yet to buy a 64-bit system. Due to the lack of OS support I am
unable to buy one. I just want to run Linux on a 64-bit system. Can
you please provide me a pointer, where I can readily get IA-64 Linux
Distributable.
Your question has nothing to do with C, or even with this discussion.
Try a Linux-specific newsgroup.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 6 '07 #20
On Wed, 6 Jun 2007 00:32:13 +0200 (CEST), J Caesar
<in*****@nospam.comwrote:
>On 5 Jun 2007 at 22:12, Richard Tobin wrote:
>You're right, you can't. But why do you want to? What are you trying
to achieve?

Note that you can compare pointers for equality even if they are
from different objects.

This gives one method: write a wrapper to malloc to store a pointer to
each block allocated together with the size of the block. Then do an
exhaustive search over all pointers to all elements of all blocks
allocated to find which blocks p and q are in (only needs you to compare
each pointer for equality with p or q, which is legal). And you're done.
p or q may be interior pointers to a malloc'd block.

Just comparing them for equality with the base address won't work.
You need to compare base <= p < (base+size), at which point you're
back to undefined behavior if p is not a pointer into the block.

There isn't any way to do it portably unless you control allocation.
If you use your own heap functions and arrange that all allocations
are made from an array under your control, then you can safely compare
any pointers into those blocks.

But it still won't help in the general case. Technically, by the
standard, comparing unrelated pointers in any way (even for equality)
produces undefined behavior. The exception is that any pointer may be
compared against the constant NULL ... but then the value of NULL is
implementation defined and _not_ guaranteed to be zero.
People have been writing technically non-portable pointer code since
the beginning. Most have just been lucky that the platforms they
targeted had memory layouts which coincidentally corresponded to the
definition of a C array and pointers were simple addresses. As Walter
Roberson mentioned earlier, there are systems in which the notion of a
pointer is more complicated. There are even some systems in which
memory is not organized as an array.

George
--
for email reply remove "/" from address
Jun 6 '07 #21
On 2007-06-06 12:28:36 -0700, George Neuner <gneuner2/@comcast.netsaid:
But it still won't help in the general case. Technically, by the
standard, comparing unrelated pointers in any way (even for equality)
produces undefined behavior.
No, comparing for equality is specifically allowed by the standard.
The exception is that any pointer may be
compared against the constant NULL ... but then the value of NULL is
implementation defined and _not_ guaranteed to be zero.

--
Clark S. Cox III
cl*******@gmail.com

Jun 6 '07 #22
George Neuner wrote:
On Wed, 6 Jun 2007 00:32:13 +0200 (CEST), J Caesar
<in*****@nospam.comwrote:
>>On 5 Jun 2007 at 22:12, Richard Tobin wrote:
>>You're right, you can't. But why do you want to? What are you trying
to achieve?

Note that you can compare pointers for equality even if they are
from different objects.

This gives one method: write a wrapper to malloc to store a pointer to
each block allocated together with the size of the block. Then do an
exhaustive search over all pointers to all elements of all blocks
allocated to find which blocks p and q are in (only needs you to compare
each pointer for equality with p or q, which is legal). And you're done.

p or q may be interior pointers to a malloc'd block.

Just comparing them for equality with the base address won't work.
You need to compare base <= p < (base+size), at which point you're
back to undefined behavior if p is not a pointer into the block.
I think J was thinking of the brute-force approach:
>Then do an
exhaustive search over all pointers to all elements of all blocks
To see if `p` is in the block, compute all pointers from `base` to
`base + size` and compare `p` with each of them /individually/.
But it still won't help in the general case. Technically, by the
standard, comparing unrelated pointers in any way (even for equality)
produces undefined behavior.
Are you sure? (Spikey-speak for "cites, please".)
The exception is that any pointer may be
compared against the constant NULL ... but then the value of NULL is
implementation defined and _not_ guaranteed to be zero.
It's guaranteed to be a way of writing a null pointer constant,
though, as is 0 in a pointer context.

--
Non-Null Hedgehog
Otherface: Jena RDF/Owl toolkit http://jena.sourceforge.net/

Jun 6 '07 #23
On Wed, 06 Jun 2007 20:52:47 GMT, Chris Dollin
<eh@electrichedgehog.netwrote:
>George Neuner wrote:
>>
... Technically, by the
standard, comparing unrelated pointers in any way (even for equality)
produces undefined behavior.

Are you sure? (Spikey-speak for "cites, please".)
The following is long because the relevant information is spread over
several sections. It is taken from the annotated version of the C99
standard, however IIRC, the only difference vs C89/C90 WRT pointers is
the inclusion of array[nelems+1] as part of the array object's address
space.

I'm pretty sure the section/paragraph #'s are the same in the
unannotated version but I can't check it just now.

Stuff not applicable to pointer comparison has been elided.
--
6.3.2.3 Conversions (Pointers)

739 A pointer to void may be converted to or from a pointer to any
incomplete or object type.

740 A pointer to any incomplete or object type may be converted to a
pointer to void and back again;

741 the result shall compare equal to the original pointer.

742 For any qualifier q, a pointer to a non-q-qualified type may be
converted to a pointer to the q-qualified version of the type;

743 the values stored in the original and converted pointers shall
compare equal.

744 An integer constant expression with the value 0, or such an
expression cast to type void *, is called a null pointer constant.

Commentary: Many implementations use an execution-time representation
of all bits zero as the value of the null pointer constant.
Implementations for processors that use a segmented memory
architecture have a number of choices for the representation of the
null pointer. The Inmos Transputer has a signed address space with
zero in the middle. It used the value 0x80000000 as its execution-time
representation. The IBM/390 running CICS also used this value.

Technically there is a distinction between a null pointer constant and
a null pointer. In practice implementations rarely make a distinction.
It is debatable whether there is a worthwhile benefit in trying to
educate developers to distinguish between the two terms.

744.1 The null pointer constant shall only be represented in the
visible form of source code by the NULL macro.

745 If a null pointer constant is converted to a pointer type, the
resulting pointer, called a null pointer, is guaranteed to compare
unequal to a pointer to any object or function.

746 Conversion of a null pointer to another pointer type yields a null
pointer of that type.

747 Any two null pointers shall compare equal.
--

6.5.8 Relational Operators

1193 For the purposes of these operators, a pointer to an object that
is not an element of an array behaves the same as a pointer to the
first element of an array of length one with the type of the object as
its element type.

1194 When two pointers are compared, the result depends on the
relative locations in the address space of the objects pointed to.

Commentary: Here the term "address space" refers to the object within
which the two pointers point. It is not being used in the common usage
sense of the address space of the program, which refers to all the
storage locations available to an executing program. The standard does
not define the absolute location of any object or subobject. However,
in some cases it does define their locations relative to other
subobjects.

1195 If two pointers to object or incomplete types both point to the
same object, or both point one past the last element of the same array
object, they compare equal.

1196 If the objects pointed to are members of the same aggregate
object, pointers to structure members declared later compare greater
than pointers to members declared earlier in the structure, and
pointers to array elements with larger subscript values compare
greater than pointers to elements of the same array with lower
subscript values.

1197 All pointers to members of the same union object compare equal.

1198 If the expression P points to an element of an array object and
the expression Q points to the last element of the same array object,
the pointer expression Q+1 compares greater than P.

1199 In all other cases, the behavior is undefined.

Commentary: The C relational operator model enables pointers to
objects to be treated in the same way as indexes into array objects.
Relational comparisons between indexes into two different array
objects (that are not both subobjects of a larger object) rarely have
any meaning and the standard does not define such support for
pointers. Some applications do need to make use of information on the
relative locations of different objects in storage. However, this
usage was not considered to be of sufficient general utility for the
Committee to specify a model defining the behavior.
--

6.5.9 Equality Operators

1203 One of the following shall hold:

:

1205 both operands are pointers to qualified or unqualified versions
of compatible types;

Commentary: The rationale for supporting pointers to qualified or
unqualified type is the same as for pointer subtraction and relational
operators. Differences in the qualification of pointed-to types is
guaranteed not to affect the equality status of two pointer values.
The operands may have a pointer to function type.

The discussion on the relational operators is applicable here.

1206 one operand is a pointer to an object or incomplete type and the
other is a pointer to a qualified or unqualified version of void;

Commentary:This combination of operands supports the idea that pointer
to void represents a generic container for any pointer type. Relaxing
the constraint in the previous C sentence, requiring the pointer types
to be compatible, removes the need for an explicit cast of the operand
having pointer to void type. A pointer to void is only guaranteed to
compare equal to the original pointer value when it is converted back
to that value’s original pointer type.

1207 one operand is a pointer and the other is a null pointer
constant.

:

1220 If one operand is a pointer and the other is a null pointer
constant, the null pointer constant is converted to the type of the
pointer.

1221 If one operand is a pointer to an object or incomplete type and
the other is a pointer to a qualified or unqualified version of void,
the former is converted to the type of the latter.

1222 For the purposes of these operators, a pointer to an object that
is not an element of an array behaves the same as a pointer to the
first element of an array of length one with the type of the object as
its element type.

1223 Two pointers compare equal if and only if both are null pointers,
both are pointers to the same object (including a pointer to an object
and a subobject at its beginning) or function, both are pointers to
one past the last element of the same array object, or one is a
pointer to one past the end of one array object and the other is a
pointer to the start of a different array object that happens to
immediately follow the first array object in the address space.
--

AFAICT comparisons between pointers, including equality, are defined
only for

1) "compatible" pointers, which by 1194 are defined as pointers of the
same type pointing into the same address space - ie. to the same
object or into the same array.
2) Pointers to void including expressions involving one pointer to
void and one pointer of another type. The non-void pointer is cast to
void before the comparison is made.
3) Null pointer constants including expressions involving one null
pointer constant and one pointer of another type. The null constant
pointer is cast to the other pointer's type before the comparison is
made.

By my reading, pointers to unrelated objects, excepting to different
members of the same array, do not meet the "address space" requirement
of the relational operators (1194) and thus are not "compatible" for
the purposes of equality (1205).

The fact that it just works in most implementations does not make it
either correct or portable.

>The exception is that any pointer may be
compared against the constant NULL ... but then the value of NULL is
implementation defined and _not_ guaranteed to be zero.

It's guaranteed to be a way of writing a null pointer constant,
though, as is 0 in a pointer context.
Almost. ((void*)0) is guaranteed to be a null pointer constant and
that pointer constant may be further cast to another pointer type.
Directly casting zero to a non-void pointer type does not, AFAICT,
portably yield a null pointer constant.

George
--
for email reply remove "/" from address
Jun 7 '07 #24
George Neuner <gneuner2/@comcast.netwrites:
On Wed, 06 Jun 2007 20:52:47 GMT, Chris Dollin
<eh@electrichedgehog.netwrote:
>>George Neuner wrote:
>>>
... Technically, by the
standard, comparing unrelated pointers in any way (even for equality)
produces undefined behavior.

Are you sure? (Spikey-speak for "cites, please".)

The following is long because the relevant information is spread over
several sections. It is taken from the annotated version of the C99
standard, however IIRC, the only difference vs C89/C90 WRT pointers is
the inclusion of array[nelems+1] as part of the array object's address
space.

I'm pretty sure the section/paragraph #'s are the same in the
unannotated version but I can't check it just now.
[big snip]
By my reading, pointers to unrelated objects, excepting to different
members of the same array, do not meet the "address space" requirement
of the relational operators (1194) and thus are not "compatible" for
the purposes of equality (1205).

The fact that it just works in most implementations does not make it
either correct or portable.
I think you've misinterpreted. You really only need two paragraphs
from the standard, C99 6.5.9p5-6 (Equality operators):

Otherwise, at least one operand is a pointer. If one operand is a
pointer and the other is a null pointer constant, the null pointer
constant is converted to the type of the pointer. If one operand
is a pointer to an object or incomplete type and the other is a
pointer to a qualified or unqualified version of void, the former
is converted to the type of the latter.

Two pointers compare equal if and only if both are null pointers,
both are pointers to the same object (including a pointer to an
object and a subobject at its beginning) or function, both are
pointers to one past the last element of the same array object, or
one is a pointer to one past the end of one array object and the
other is a pointer to the start of a different array object that
happens to immediately follow the first array object in the
address space

The preceding section, on relational operators (<, <=, >, >=)
specifically states that the behavior is undefined except in certain
cases. There is no such statement in the section on equality
operators. As long as both pointers have valid (not indeterminate)
values, "=" and "!=" will yield 1 and 0, respectively, if they're
equal, and 0 and 1, respectively, if they aren't.
>>The exception is that any pointer may be
compared against the constant NULL ... but then the value of NULL is
implementation defined and _not_ guaranteed to be zero.

It's guaranteed to be a way of writing a null pointer constant,
though, as is 0 in a pointer context.

Almost. ((void*)0) is guaranteed to be a null pointer constant and
that pointer constant may be further cast to another pointer type.
Directly casting zero to a non-void pointer type does not, AFAICT,
portably yield a null pointer constant.
Whether something is a null pointer constant is not a matter of
portability. A null pointer constant is an unambiguous source code
construct, not to be confused with a null pointer, which is a run-time
value. Specifically, C99 6.3.2.3p3:

An integer constant expression with the value 0, or such an
expression cast to type void *, is called a _null pointer
constant_. If a null pointer constant is converted to a pointer
type, the resulting pointer, called a _null pointer_, is
guaranteed to compare unequal to a pointer to any object or
function.

So casting anything to a type other than void* cannot yield a null
pointer constant, but converting a null pointer constant to any
pointer type yields (at run time) a null pointer value.

(There's a slight glitch in the wording of the standard, such that
it's not clear that a parenthesized null pointer constant such as
((void*)0) is a null pointer constant, but it's clearly intended that
it should be.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 7 '07 #25
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>I think you've misinterpreted. You really only need two paragraphs
from the standard, C99 6.5.9p5-6 (Equality operators):
Two pointers compare equal if and only if both are null pointers,
both are pointers to the same object (including a pointer to an
object and a subobject at its beginning) or function, both are
pointers to one past the last element of the same array object, or
one is a pointer to one past the end of one array object and the
other is a pointer to the start of a different array object that
happens to immediately follow the first array object in the
address space
FYI, C89 3.5.9 lacked the 'if and only if', and used different
phrasing that was a little ambiguous:

If two pointers to object or incomplete types compare equal,
they are both null pointers, or both point to the same object, or
both point one past the last element of the same array object.

This wording doesn't -quite- indicate that comparing between different
objects is defined: "if this succeeds then", but if it doesn't succeed
then possibly the comparison results in 0 or possibly you get
some kind of exception. There is nothing in the Constraints portion
of the C89 section to indicate that comparing between different objects
is disallowed, which makes the "or possibly you get some kind of
exception" argument noticably weaker (some might say denies it entirely.)
--
Programming is what happens while you're busy making other plans.
Jun 7 '07 #26

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Sayan | last post by:
How do I distinguish between a heap pointer and a stack pointer? I want the following to work: template<class T> bool isHeapPtr(T* p1,T* p2);//the function I want to write //... int a = 5;...
27
by: glen herrmannsfeldt | last post by:
The subject recently came up in comp.compilers, though I believe that I asked here before. If you use relational operators, other than == and !=, on pointers to different objects, is there any...
20
by: Bill Pursell | last post by:
This question involves code relying on mmap, and thus is not maximally portable. Undoubtedly, many will complain that my question is not topical... I have two pointers, the first of which is...
66
by: Praveen | last post by:
Hi, I came across a program as follows main() { int x, y ; int *p1 = &x; int *p2 = &y; printf("%d\n", p1-p2); }
12
by: Michael Bell | last post by:
I am trying to put my learning effort into the most useful things. What do pointers do that other things can't? Michael Bell --
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: Aftab Ahmad | last post by:
Hello Experts! I have written a code in MS Access for a cmd called "WhatsApp Message" to open WhatsApp using that very code but the problem is that it gives a popup message everytime I clicked on...
0
by: Aftab Ahmad | last post by:
So, I have written a code for a cmd called "Send WhatsApp Message" to open and send WhatsApp messaage. The code is given below. Dim IE As Object Set IE =...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.