473,834 Members | 1,419 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

comparing ptrs/mmap

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 mmapped
to a single page. I want to determine if the second
is on the page. I'd like to do:

#include "platform_appro priate_definiti on_of_PAGESIZE. h"
int compare1(const char *a, const char *b)
{
return (b>=a && b-a < PAGESIZE);
}

but this is clearly not legal, since I'm comparing
pointers that may not be comparable.

I'm further tempted to something like:

int compare2(const void *a, const void *b)
{
return ( ((int)b & PAGE_MASK) == (int)a);
}

I believe compare2 will work on any platform which
satisfies sizeof (int) == sizeof (void *) and on which
one can provide a suitable definition of PAGE_MASK.

I want to know if there are any language issues
involved with compare2() of which I should be aware.
Also, is there a way to write compare1() that is safe?

Finally, where in the FAQ is the question:
when is it safe to compare pointers? My understanding
is that a < b is safe if a and b point into the same object,
but I don't find that in the FAQ anywhere.

--
Bill Pursell

Nov 2 '06 #1
20 2171

Bill Pursell wrote:
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 mmapped
to a single page. I want to determine if the second
is on the page. I'd like to do:

#include "platform_appro priate_definiti on_of_PAGESIZE. h"
int compare1(const char *a, const char *b)
{
return (b>=a && b-a < PAGESIZE);
}

but this is clearly not legal, since I'm comparing
pointers that may not be comparable.

I'm further tempted to something like:

int compare2(const void *a, const void *b)
{
return ( ((int)b & PAGE_MASK) == (int)a);
}

I believe compare2 will work on any platform which
satisfies sizeof (int) == sizeof (void *) and on which
one can provide a suitable definition of PAGE_MASK.

I want to know if there are any language issues
involved with compare2() of which I should be aware.
Also, is there a way to write compare1() that is safe?

Finally, where in the FAQ is the question:
when is it safe to compare pointers? My understanding
is that a < b is safe if a and b point into the same object,
but I don't find that in the FAQ anywhere.
While the OT mmap may introduce guarantees about the nature of
pointers, there are certainly platforms that do not implement pointers
in a way that would allow compare1() or compare2() to produce the
result you want. Perhaps the most familiar is x86 segmented
addressing, uncommon on 32 bit OS, but universal on older 16 bit OSs.
Such a pointer consists of a segment ID and offset within the specified
segment. The actual relationship between segments and pages is up to
the OS, and may be quite complex. Thus 1234:0123, 2345:0123 and
3456:9876 might refer to the same location, different locations on the
same page, or different pages entirely (assuming that the system has
pages).

And fundamentally, the result of casting a pointer to an int is
specifically not portable.

BTW, compare2() needs to mask the value on the right side of the
comparison too.

Nov 2 '06 #2
On Thu, 2 Nov 2006 06:57:18 UTC, "Bill Pursell"
<bi**********@g mail.comwrote:
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 mmapped
to a single page. I want to determine if the second
is on the page. I'd like to do:

#include "platform_appro priate_definiti on_of_PAGESIZE. h"
int compare1(const char *a, const char *b)
{
return (b>=a && b-a < PAGESIZE);
}

but this is clearly not legal, since I'm comparing
pointers that may not be comparable.
That is clearly absolutely legal. At least when the assumption the
whole procedure does is true that both pointers are referencing to the
same object.
I'm further tempted to something like:

int compare2(const void *a, const void *b)
{
return ( ((int)b & PAGE_MASK) == (int)a);
}
And that is absolutely illegal because there is nothing that can
guarantee that pointer can ever casted to int. compare() will work on
each system, compare2 ends in undefined behavior.
I believe compare2 will work on any platform which
satisfies sizeof (int) == sizeof (void *) and on which
one can provide a suitable definition of PAGE_MASK.
Nowhay. There is nothing that guaratees that size_t matches sizof
void* or even sizeof int. You're here deep inside the lands of
undefined behavior.
I want to know if there are any language issues
involved with compare2() of which I should be aware.
Also, is there a way to write compare1() that is safe?
The way you showed us is well defined on any system solong both
pointers are coming in as they should by the definition of the system.
When not there is absolutely no way you can work with any realtion of
both pointers.
Finally, where in the FAQ is the question:
when is it safe to compare pointers? My understanding
is that a < b is safe if a and b point into the same object,
but I don't find that in the FAQ anywhere.
That is guaranteed by the standard solong b points not outside the
last member of the object and a is inside the range of first and
last+1.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
Nov 2 '06 #3
Herbert Rosenau wrote:
On Thu, 2 Nov 2006 06:57:18 UTC, "Bill Pursell"
<bi**********@g mail.comwrote:

I have two pointers, the first of which is mmapped
to a single page. I want to determine if the second
is on the page. I'd like to do:

#include "platform_appro priate_definiti on_of_PAGESIZE. h"
int compare1(const char *a, const char *b)
{
return (b>=a && b-a < PAGESIZE);
}

but this is clearly not legal, since I'm comparing
pointers that may not be comparable.

That is clearly absolutely legal. At least when the assumption the
whole procedure does is true that both pointers are referencing to the
same object.
I don't know if the pointers reference the same object, and
that's what I'm trying to cope with. I can remove the issue
of mmap from the thread and re-phrase the question this
way: suppose I have a list of objects and a pointer:

struct obj_list {
struct obj *data;
struct obj_list *next;
} list;

void *b;

I know that b lies in one of the objects, but I don't know
which one. How do I figure out which one it's in? The
obvious thing is to compare b with data for each data
pointer in the list ( b (void *)data && b < (void *)(data + 1)),
but that means that most of the comparisons
are being done on pointers that aren't in the same object.
--
Bill Pursell

Nov 2 '06 #4
On Thu, 2 Nov 2006 07:56:14 UTC, "ro***********@ yahoo.com"
<ro***********@ yahoo.comwrote:
While the OT mmap may introduce guarantees about the nature of
pointers, there are certainly platforms that do not implement pointers
in a way that would allow compare1() or compare2() to produce the
result you want.
Clearly wrong. compare1() is clearly standard conform and each C
Compiler that is itself a real C compiler, that means it is standard
conform will produce code that lets compare1() flawless until the
assumption the function does is fullifyed. No conforming C compiler
will ever guarantee that compar2() will not end in the lands of
undefined behavior.

Perhaps the most familiar is x86 segmented

Dosn't matter because compare1 is completely conforming.
addressing, uncommon on 32 bit OS, but universal on older 16 bit OSs.
Such a pointer consists of a segment ID and offset within the specified
segment. The actual relationship between segments and pages is up to
the OS, and may be quite complex. Thus 1234:0123, 2345:0123 and
3456:9876 might refer to the same location, different locations on the
same page, or different pages entirely (assuming that the system has
pages).
If the pointers are pointing inside the same array there is no problem
at all with compare1 - but always with compare2().
>
And fundamentally, the result of casting a pointer to an int is
specifically not portable.
Yepp.
BTW, compare2() needs to mask the value on the right side of the
comparison too.
And even then it is not conform.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
Nov 2 '06 #5
In article <wm************ *************** @JUPITER1.PC-ROSENAU.DE>,
Herbert Rosenau <os****@pc-rosenau.dewrote :
>>>I have two pointers, the first of which is mmapped
to a single page. I want to determine if the second
is on the page. I'd like to do:
>>>#include "platform_appro priate_definiti on_of_PAGESIZE. h"
int compare1(const char *a, const char *b)
{
return (b>=a && b-a < PAGESIZE);
}
>Clearly wrong. compare1() is clearly standard conform and each C
Compiler that is itself a real C compiler, that means it is standard
conform will produce code that lets compare1() flawless until the
assumption the function does is fullifyed.
I seem to be stuck in a mental loop somewhere, somehow blind to
the standard conformance of compare1(). As it is clear to you, I
would appreciate you pointing out where my logic has gone wrong, or
which section of the standard that I am missing?

The original poster has two pointers, which are NOT necessarily to
the same object.

The compare1() function starts by attempting to compare the functions
using the >= operator. I can't seem to get out of my head that
in C89 the appropriate section of the standard is 3.3.8 "Relational
Operators".

The two types being compared via >= are the same, so there is no
violation of the Constraints subsection of 3.3.8, so we look at the
Semantics section. As the conformance of the code is clear to you,
I must be misreading or misinterpreting that section, as I keep
finding these sentances:

If the objects pointed to are not members of the same aggregate or
union object, the result is undefined, with the following exception.
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 higher than P, even though Q+1
does not point to an elment of the array object.

Not pointers to the same object, "the result is undefined". Is the
original poster passing in pointers that are certain to be pointing to
the same object, or certain to be fall into the one exception? No. So
if the original poster passes in pointers to different objects, is the
code standard conforming? I, in my mental blindness, keep seeing that
"the result is undefined" section of the C89 standard. But Herbert
says the code is "clearly standard conform", so I must be missing
something.

Ah, I see a possibility: perhaps code can actively use an "undefined"
result, and yet still be standard conforming? Is that it, Herbert?
Are you saying that using a result that is apparently specifically
undefined according to the standard, still "clearly standard conform" ??
Is that where my mental block is, am I just hung up on thinking
that undefined results are *not* standard conforming?? Herbert, is
code that uses undefined behaviour standard conforming unless it
violates a Constraint??
--
All is vanity. -- Ecclesiastes
Nov 2 '06 #6
"Bill Pursell" <bi**********@g mail.comwrites:
[...]
I don't know if the pointers reference the same object, and
that's what I'm trying to cope with. I can remove the issue
of mmap from the thread and re-phrase the question this
way: suppose I have a list of objects and a pointer:

struct obj_list {
struct obj *data;
struct obj_list *next;
} list;

void *b;

I know that b lies in one of the objects, but I don't know
which one. How do I figure out which one it's in? The
obvious thing is to compare b with data for each data
pointer in the list ( b (void *)data && b < (void *)(data + 1)),
but that means that most of the comparisons
are being done on pointers that aren't in the same object.
Comparing two pointers using a relational operator (<, <=, >, >=)
invokes undefined behavior if the pointers do no point into the same
object or just past the end of it. But any pointers can safely be
compared for equality.

So if you have a collection of distinct objects, and you want to know
whether a given pointer points to, or within, or just past the end of,
one of them (and which one), you can treat each object as an array of
unsigned char and test the pointer for equality against a pointer to
each byte of each object. This avoids undefined behavior, but it's
obviously horrendously inefficient.

If you can live with a bit of undefined behavior, you can use "<" and
">" to see whether the pointer is within the range of addresses for
each object (2 comparisons per object rather than (sizeof obj)
comparisons per object); if you find an apparent match, you can then
confirm it with equality comparisons for each byte. This should work
as long as the undefined behavior of the "<" and ">" operators is no
worse than yielding a possibly incorrect result. Keep the code
isolated and well commented.

In either case, if you know that the pointer points only to a certain
location within the object (to the beginning, or to a certain member),
you can save a lot of effort.

(Or you can throw caution to the wind and assume a linear address
space; your code will probably work on most systems, and won't break
until the most inconvenient possible moment.)

--
Keith Thompson (The_Other_Keit h) 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.
Nov 2 '06 #7
Herbert Rosenau wrote:
On Thu, 2 Nov 2006 06:57:18 UTC, "Bill Pursell"
<bi**********@g mail.comwrote:
>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 mmapped
to a single page. I want to determine if the second
is on the page. I'd like to do:

#include "platform_appro priate_definiti on_of_PAGESIZE. h"
int compare1(const char *a, const char *b)
{
return (b>=a && b-a < PAGESIZE);
}

but this is clearly not legal, since I'm comparing
pointers that may not be comparable.

That is clearly absolutely legal. At least when the assumption the
whole procedure does is true that both pointers are referencing to the
same object.
Yes, but that is exactly the assumption that the OP said he couldn't
make. He doesn't know that they point into (or one past) the same
object. Therefore, compare1 is not legal. Seeing as he is using mmap,
there may be some other guarantees of the ability to compare pointers
given by POSIX or other appropriate standard. But, from a standard C
point of view he is invoking undefined behavior.
>I'm further tempted to something like:

int compare2(const void *a, const void *b)
{
return ( ((int)b & PAGE_MASK) == (int)a);
}

And that is absolutely illegal because there is nothing that can
guarantee that pointer can ever casted to int. compare() will work on
each system, compare2 ends in undefined behavior.
compare2 is implementation defined.

--
Clark S. Cox III
cl*******@gmail .com
Nov 2 '06 #8
In article <ln************ @nuthaus.mib.or g>,
Keith Thompson <ks***@mib.orgw rote:
>Comparing two pointers using a relational operator (<, <=, >, >=)
invokes undefined behavior if the pointers do no point into the same
object or just past the end of it. But any pointers can safely be
compared for equality.
That's not clear to me, looking at C89. 3.3.9 Equality Operators
specifies that "Where the operands have types and values suitable
for the relational operators, the semantics detailed in 3.3.8 apply".
3.3.8 on relational operators restricts the definedness of the
comparisons to pointers to the same object (or one past). 3.3.8
does specifically mention equality of pointers, in the paragraph
after saying the result of the relational comparison is undefined
if it isn't the same object (or one past).

C89 3.3.9 does give meaning to comparisons with NULL where 3.3.8
does not. The wording in 3.3.9 about equality of pointers is otherwise
substantially the same as the equality paragraph of 3.3.8. Two
null pointers compare equal. If two pointers 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. But that
statement doesn't say that it is defined for two pointers to different
objects to be compared. So I would say that the reference to the
3.3.8 semantics is in force when not comparing to NULL, and thus that
the result of the equality test is undefined unless it is the same
object (or null or one past the same object.)

--
Programming is what happens while you're busy making other plans.
Nov 2 '06 #9
ro******@ibd.nr c-cnrc.gc.ca (Walter Roberson) writes:
In article <ln************ @nuthaus.mib.or g>,
Keith Thompson <ks***@mib.orgw rote:
>>Comparing two pointers using a relational operator (<, <=, >, >=)
invokes undefined behavior if the pointers do no point into the same
object or just past the end of it. But any pointers can safely be
compared for equality.

That's not clear to me, looking at C89. 3.3.9 Equality Operators
specifies that "Where the operands have types and values suitable
for the relational operators, the semantics detailed in 3.3.8 apply".
3.3.8 on relational operators restricts the definedness of the
comparisons to pointers to the same object (or one past). 3.3.8
does specifically mention equality of pointers, in the paragraph
after saying the result of the relational comparison is undefined
if it isn't the same object (or one past).

C89 3.3.9 does give meaning to comparisons with NULL where 3.3.8
does not. The wording in 3.3.9 about equality of pointers is otherwise
substantially the same as the equality paragraph of 3.3.8. Two
null pointers compare equal. If two pointers 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. But that
statement doesn't say that it is defined for two pointers to different
objects to be compared. So I would say that the reference to the
3.3.8 semantics is in force when not comparing to NULL, and thus that
the result of the equality test is undefined unless it is the same
object (or null or one past the same object.)
It's not 100% clear to me either (from the C90 standard). But C99
makes it clearer. C99 6.5.9p3:

The == (equal to) and != (not equal to) operators are analogous to
the relational operators except for their lower precedence.91)
Each of the operators yields 1 if the specified relation is true
and 0 if it is false. The result has type int. For any pair of
operands, exactly one of the relations is true.

C99 6.5.9p6:

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.

--
Keith Thompson (The_Other_Keit h) 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.
Nov 2 '06 #10

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

Similar topics

4
3546
by: Hao Xu | last post by:
Hi everyone! I found that if you want to write to the memory got by mmap(), you have to get the file descriptor for mmap() in O_RDWR mode. If you got the file descriptor in O_WRONLY mode, then writing to the memory got by mmap() will lead to segmentation fault. Anyone knows why? Is this a rule or a bug? What if I just want to write to the file and nothing else?
4
3711
by: Fabiano Sidler | last post by:
Hi folks! I created an mmap object like so: --- snip --- from mmap import mmap,MAP_ANONYMOUS,MAP_PRIVATE fl = file('/dev/zero','rw') mm = mmap(fl.fileno(), 1, MAP_PRIVATE|MAP_ANONYMOUS) --- snap --- Now, when I try to resize mm to 10 byte
1
5475
by: James T. Dennis | last post by:
I've been thinking about the Python mmap module quite a bit during the last couple of days. Sadly most of it has just been thinking ... and reading pages from Google searches ... and very little of it as been coding. Mostly it's just academic curiosity (I might be teaching an "overview of programming" class in a few months, and I'd use Python for most of the practical examples to cover a broad range of programming topics, including the...
1
2699
by: koara | last post by:
Hello all, i am using the mmap module (python2.4) to access contents of a file. My question regards the relative performance of mmap.seek() vs mmap.tell(). I have a generator that returns stuff from the file, piece by piece. Since other things may happen to the mmap object in between consecutive next() calls (such as another iterator's next()), i have to store the file position before yield and restore it afterwards by means of tell()...
2
4641
by: Neal Becker | last post by:
On linux, I don't understand why: f = open ('/dev/eos', 'rw') m = mmap.mmap(f.fileno(), 1000000, prot=mmap.PROT_READ|mmap.PROT_WRITE, flags=mmap.MAP_SHARED) gives 'permission denied', but this c++ code works: #include <sys/mman.h> #include <fcntl.h>
0
1154
by: Kris Kennaway | last post by:
If I do the following: def mmap_search(f, string): fh = file(f) mm = mmap.mmap(fh.fileno(), 0, mmap.MAP_SHARED, mmap.PROT_READ) return mm.find(string) def mmap_is_in(f, string): fh = file(f)
0
1125
by: Gabriel Genellina | last post by:
En Thu, 29 May 2008 19:17:05 -0300, Kris Kennaway <kris@FreeBSD.org> escribió: Looks like you should define the sq_contains member in mmap_as_sequence, and the type should have the Py_TPFLAGS_HAVE_SEQUENCE_IN flag set (all in mmapmodule.c) -- Gabriel Genellina
1
1687
by: magnus.lycka | last post by:
Does anyone recognize this little Python crasher? I'll file a bug report unless someone notices it as an already documented bug. I found some open mmap bugs, but it wasn't obvious to me that this problem was one of those... Python 2.5.2 (r252:60911, Apr 21 2008, 11:12:42) on linux2 Type "help", "copyright", "credits" or "license" for more information. Segmenteringsfel (core dumped)
0
1965
by: Akira Kitada | last post by:
Hi Marc-Andre, Thanks for the suggestion. I opened a ticket for this issue: http://bugs.python.org/issue4204 Now I understand the state of the multiprocessing module, but it's too bad to see math, mmap and readline modules, that worked fine before, cannot be built anymore.
0
9796
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9643
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,...
1
10545
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
9329
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
7755
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
6952
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5624
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...
1
4425
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
3079
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.