473,804 Members | 3,722 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

ptr1 == ptr2 but (int)ptr1 != (int)ptr2

Do anyone know of an architecture where this can break?

T *ptr1, *ptr2;
...
if (ptr1 == ptr2)
if (CHAR_BIT*sizeo f(T*) <= (width of int)) /*otherwise undefined*/
assert((int)ptr 1 == (int)ptr2);

(Feel free to replace int with another integer type if that helps to
break something.)

I know an addess can have several representations at least on some DOS
memory models, but I don't know if it normalizes pointers before
converting to integer.

--
Regards,
Hallvard
May 25 '07 #1
19 3263
Hallvard B Furuseth wrote:
>
Do anyone know of an architecture where this can break?

T *ptr1, *ptr2;
...
if (ptr1 == ptr2)
if (CHAR_BIT*sizeo f(T*) <= (width of int)) /*otherwise undefined*/
assert((int)ptr 1 == (int)ptr2);

(Feel free to replace int with another integer type if that helps to
break something.)

I know an addess can have several representations at least on some DOS
memory models, but I don't know if it normalizes pointers before
converting to integer.
I would suspect that, on most platforms in which a pointer can fit
into an int, if the pointers compare equal, then the converted-to-int
values will also compare equal.

However, I'm sure the standard probably says it's implementation
defined at best.

Consider a segmented memory architecture, such as "real-mode" on
the x86 line of processors. On such platforms "far" pointers are
32 bits (16-bit segment, plus 16-bit offset), and I would suspect
that it may be possible for two pointers to compare equal, even
if their bit patterns are not identical. (For example, it may
compare FFFF:0000 and F000:FFF0 as "equal", but 0xFFFF0000 and
0xF000FFF0 as ints [or perhaps longs] will not compare equal.)

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer .h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th***** ********@gmail. com>

May 25 '07 #2

"Hallvard B Furuseth" <h.**********@u sit.uio.nowrote in message
news:hb******** ******@bombur.u io.no...
Do anyone know of an architecture where this can break?

T *ptr1, *ptr2;
...
if (ptr1 == ptr2)
if (CHAR_BIT*sizeo f(T*) <= (width of int)) /*otherwise undefined*/
assert((int)ptr 1 == (int)ptr2);

(Feel free to replace int with another integer type if that helps to
break something.)

I know an addess can have several representations at least on some DOS
memory models, but I don't know if it normalizes pointers before
converting to integer.
I'd be surprised if it does. If someone wants to convert a pointer to an
integer normally they want to get at the bits, so reinterpretatio n seems
likely. That would mean that if the same address has two interpretations , it
would break.

However in reality ptr1 == ptr2 would almost certainly break as well. That
is why it is illegal to create a pointer that roams over more than one
object. If the architecture is segmented, probably the only C way of
generating two different pointers to the same physical address is to move
one beyond its range. So at runtime the program can cheaply compare pointer
for equality by comaring bits, and doesn't need a normalisation step.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
May 26 '07 #3
Malcolm McLean wrote:
>
"Hallvard B Furuseth" <h.**********@u sit.uio.nowrote in message
news:hb******** ******@bombur.u io.no...
>Do anyone know of an architecture where this can break?

T *ptr1, *ptr2;
...
if (ptr1 == ptr2)
if (CHAR_BIT*sizeo f(T*) <= (width of int)) /*otherwise undefined*/
assert((int)ptr 1 == (int)ptr2);

(Feel free to replace int with another integer type if that helps to
break something.)

I know an addess can have several representations at least on some DOS
memory models, but I don't know if it normalizes pointers before
converting to integer.
I'd be surprised if it does. If someone wants to convert a pointer to an
integer normally they want to get at the bits, so reinterpretatio n seems
likely. That would mean that if the same address has two
interpretations , it would break.

However in reality ptr1 == ptr2 would almost certainly break as well.
No, ptr1==ptr2 is guaranteed by the standard to always work[1] whether
or not the pointers have any relationship to each other and whether or
not they use different representations for the same value.
That is why it is illegal to create a pointer that roams over more than
one object.
That is a separate matter from whether different representations can be
used for the same pointer value. It allows for range checking
implementations , something which does exist and does not require there
to be different representations of the same physical address.
If the architecture is segmented, probably the only C way of
generating two different pointers to the same physical address is to
move one beyond its range.
Wrong. The architecture could have overlapping segments such that:
{
int arr[4069]; /* arr starts in segment 1 */
int *ptr1 = a+1024; /* ptr1 starts in segment 2 */
int *ptr2 = a+4096; /* ptr2 starts in segment 3 */
while (ptr1 != ptr2) ptr2--;
Then they meet when ptr1 is using segment 2 but ptr2 is using segment 3.
The compiler has to make it work.

The good old x86 range of processors uses overlapping segments, although
I don't know if any compilers allowed objects (or malloced regions)
larger than a segment.
So at runtime the program can cheaply compare
pointer for equality by comaring bits, and doesn't need a normalisation
step.
Wrong. The standard guarantees that comparing for equality always works.
It is only relational operators excluding equality and inequality that
do not have to work.

[1] If one of the pointers is neither null, nor a pointer to an object,
nor a pointer to 1 past an object, then undefined behaviour occurs on
evaluating the pointer before you get as far as the comparison.
--
Flash Gordon
May 26 '07 #4

"Flash Gordon" <sp**@flash-gordon.me.ukwro te in message
news:sb******** ****@news.flash-gordon.me.uk...
Malcolm McLean wrote:
So at runtime the program can cheaply compare
pointer for equality by comaring bits, and doesn't need a normalisation
step.

Wrong. The standard guarantees that comparing for equality always works.
It is only relational operators excluding equality and inequality that do
not have to work.
Once your pointer holds an illegal address, any other operations on it
become undefined. Including tests for equality. So if we move a pointer
outside its object, the test for equality with another pointer can either
fail or pass, it is undefined. Writing to that pointer may write to the same
memory location, or it might trigger a segfault, again the behaviour is UB.
So by holding objects to the size of a segment, we can implement equality
tests by a simple comparison of bits, and still conform.

You have however homed in on a problem with the standard, which is that the
"1 past is valid" rule can make correct implementation of segemented objects
difficult.
>
[1] If one of the pointers is neither null, nor a pointer to an object,
nor a pointer to 1 past an object, then undefined behaviour occurs on
evaluating the pointer before you get as far as the comparison.
You've put the right answer here. Once you execute UB, all subsequent
operations also become undefined.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

May 26 '07 #5
Malcolm McLean writes:
>Hallvard B Furuseth wrote in message
news:hb******** ******@bombur.u io.no...
>Do anyone know of an architecture where this can break?

T *ptr1, *ptr2;
...
if (ptr1 == ptr2)
if (CHAR_BIT*sizeo f(T*) <= (width of int)) /*otherwise undefined*/
assert((int)ptr 1 == (int)ptr2);

(Feel free to replace int with another integer type if that helps to
break something.)

I know an addess can have several representations at least on some DOS
memory models, but I don't know if it normalizes pointers before
converting to integer.
I'd be surprised if it does. If someone wants to convert a pointer to an
integer normally they want to get at the bits, so reinterpretatio n seems
likely. That would mean that if the same address has two
interpretations , it would break.
So, two opposite guesses about what would happen so far... that's why I
wondered if anyone knew of real-world examples.
However in reality ptr1 == ptr2 would almost certainly break as
well.
No, that can only break if ptr1 or ptr2 does not contain a valid pointer
representation. I.e. a trap representation, as C99 calls it. That's
not a different representation of another pointer value, it's more like
invalid values which accidentally could compare equal to a valid value.
That is why it is illegal to create a pointer that roams over more
than one object. If the architecture is segmented, probably the only C
way of generating two different pointers to the same physical address is
to move one beyond its range.
I'm pretty sure I've seen counterexamples of this, and that some DOS
memory model was one of them.

--
Hallvard
May 29 '07 #6
On May 26, 3:21 pm, Flash Gordon <s...@flash-gordon.me.ukwro te:
The good old x86 range of processors uses overlapping segments, although
I don't know if any compilers allowed objects (or malloced regions)
larger than a segment.
<OT, but not very>

I seem to remember a C89 implementation in which malloc wouldn't
return larger than a segment, but by using the right compiler switches
and an implementation-specific header and library, it was possible to
get objects larger than a segment. You could declare

char far* s;

to get a pointer that could point anywhere in memory (the compiler
switch made far into a keyword) but compared like intptr_t would (so
occasionally you got counter-intuitive and non-compliant behaviour
such as greater-than tests on two pointers into the same object
returning the wrong result), or

char huge* s;

to get a pointer which behaved correctly but was more expensive (i.e.
the segmentation was taken into account with extra instructions).
'far' was enough in most cases, and you needed a special
implementation-specific farmalloc to get big objects.

Of course, the special things you had to do to get this to happen
weren't C89, or any other standard that I know of. This was one of the
sorts of things that caused confusion for beginning C programmers on
DOS systems (it's linked to the whole 'memory model' thing that
nowadays compilers can thankfully take care of themselves (hint to
anyone who actually ends up having to learn C on such a system: set it
to 'small' and you'll get correct C89 behaviour without having to
worry about it any further)).

</OT>
--
ais523

May 29 '07 #7
Malcolm McLean wrote:
>
"Flash Gordon" <sp**@flash-gordon.me.ukwro te in message
news:sb******** ****@news.flash-gordon.me.uk...
Malcolm McLean wrote:
So at runtime the program can cheaply compare
pointer for equality by comaring bits, and doesn't need a normalisation
step.
Wrong. The standard guarantees that comparing for equality always works.
It is only relational operators excluding equality and inequality that do
not have to work.
Once your pointer holds an illegal address, any other operations on it
become undefined. Including tests for equality.
[...]

If you have two valid pointers to separate "objects", must an
equality test return "false"? I seem to recall that in the
segmented world of real-mode x86 systems, "far" pointers (which
consisted of a 16-bit segment and a 16-bit offset) only compared
the offset part, meaning that, if the two "objects" were at the
same offset within different segments, the pointers would compare
as equal.

Of course, it's been many years since I've done such work, so I
may be remembering incorrectly.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer .h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th***** ********@gmail. com>
May 29 '07 #8
Flash Gordon wrote:
[...]
The good old x86 range of processors uses overlapping segments, although
I don't know if any compilers allowed objects (or malloced regions)
larger than a segment.
[...]

Yes. In addition to "near" pointers (16 bit offset into the default
data segment) and "far" pointers (32 bit segment:offset) , there were
also "huge" pointers (32 bit segment:offset) which could point to
memory regions larger than a single 64K segment.
Attempting to make this on-topic...

On such architectures, the compilers would assume (rightfully so, as
far as the standard is concerned) that only the offsets would need to
be compared in non-huge pointers. Because, even though a "far"
pointer was 32 bits, you can only compare pointers within a single
object. Therefore, 1111:0080 and 2222:0080 could compare "equal".
Also, I believe that xxxx:0000 would compare equal to NULL, regardless
of the segment "xxxx" value. This would mean that 1111:0000 and
2222:0000 would both compare equal to each other, and both would
compare equal to NULL, but storing them in long ints would make them
compare unequal to each other. (Remember, the above assumes that
these pointers are "far" and not "huge".)

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer .h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th***** ********@gmail. com>
May 29 '07 #9
In article <46************ ***@spamcop.net >,
Kenneth Brody <ke******@spamc op.netwrote:
>If you have two valid pointers to separate "objects", must an
equality test return "false"?
Yes. Equality and inequality tests, unlike ordering tests, must work on
any two valid pointers of the same type, whether or not they point into
the same object, and must report inequality for pointers to different
objects.
I seem to recall that in the
segmented world of real-mode x86 systems, "far" pointers (which
consisted of a 16-bit segment and a 16-bit offset) only compared
the offset part, meaning that, if the two "objects" were at the
same offset within different segments, the pointers would compare
as equal.

Of course, it's been many years since I've done such work, so I
may be remembering incorrectly.
An implementation that did that would be non-conforming.
dave

--
Dave Vandervies dj******@csclub .uwaterloo.ca
I _am_ consistent - if one of those other pointer guide writers came
here and asked for comments, they'd get chewed out just as badly.
--Richard Bos in comp.lang.c
May 29 '07 #10

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

Similar topics

27
2129
by: sophia | last post by:
Dear all, why in the following program #include<stdio.h> #include<stdlib.h> int main(void) {
0
9569
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10558
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10302
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10069
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9130
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7608
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5503
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
3802
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2975
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.