Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Subtracting pointers: Which type to use to store the result?

Reply
Thread Tools

Subtracting pointers: Which type to use to store the result?

 
 
Spiro Trikaliotis
Guest
Posts: n/a
 
      02-23-2006
Hello,

I have a question regarding subtracting a pointer from another one.
Assume I have two pointers p1 and p2, which both point to a memory area
obtained with malloc(). Assume p1 = p2 + some value c.

Now, I want to obtain the difference between the two, that is, the value
c. Which type must I use for c?

I searched around and did not find a definitive answer (not even in the
FAQ). Anyway, http://c-faq.com/malloc/realloc.html has a code sample
which uses:

int tmpoffset;

p = malloc(10);
strcpy(p, "Hello,");/* p is a string */
p2 = strchr(p, ',');/* p2 points into that string */

tmpoffset = p2 - p;


Thus, this examples assumes that an int should be sufficient (or that
example is broken).

Unfortunately, my compiler complains on the "tmpoffset = p2 -p;" line:

file.c(745): error C4242: '=' : conversion from '__int64' to 'int', possible loss of data


(Yes, this is a 64 bit MS compiler, but that should not matter.)

Of course, I could just use __int64 type, but this does not seem the
best portable way for me. I could cast p2-p, as I know the difference
can't be that big not to fit into an int, but this is no good solution
either. Additionally, I doubt size_t to be a good candidate here,
either.

So, my question is: Thinking of portability, which type should I use
here? Or is the MS compiler wrong?

Thanks,
Spiro.

--
Spiro R. Trikaliotis http://cbm4win.sf.net/
http://www.trikaliotis.net/ http://www.viceteam.org/
 
Reply With Quote
 
 
 
 
pemo
Guest
Posts: n/a
 
      02-23-2006
Spiro Trikaliotis wrote:
> Hello,
>
> I have a question regarding subtracting a pointer from another one.
> Assume I have two pointers p1 and p2, which both point to a memory
> area
> obtained with malloc(). Assume p1 = p2 + some value c.
>
> Now, I want to obtain the difference between the two, that is, the
> value
> c. Which type must I use for c?
>
> I searched around and did not find a definitive answer (not even in
> the
> FAQ). Anyway, http://c-faq.com/malloc/realloc.html has a code sample
> which uses:
>
> int tmpoffset;
>
> p = malloc(10);
> strcpy(p, "Hello,");/* p is a string */
> p2 = strchr(p, ',');/* p2 points into that string */
>
> tmpoffset = p2 - p;
>
>
> Thus, this examples assumes that an int should be sufficient (or that
> example is broken).
>
> Unfortunately, my compiler complains on the "tmpoffset = p2 -p;" line:
>
> file.c(745): error C4242: '=' : conversion from '__int64' to 'int',
> possible loss of data
>
>
> (Yes, this is a 64 bit MS compiler, but that should not matter.)
>
> Of course, I could just use __int64 type, but this does not seem the
> best portable way for me. I could cast p2-p, as I know the difference
> can't be that big not to fit into an int, but this is no good solution
> either. Additionally, I doubt size_t to be a good candidate here,
> either.
>
> So, my question is: Thinking of portability, which type should I use
> here? Or is the MS compiler wrong?
>
> Thanks,
> Spiro.



ptrdiff_t


--
==============
*Not a pedant*
==============


 
Reply With Quote
 
 
 
 
Vladimir S. Oka
Guest
Posts: n/a
 
      02-23-2006

pemo wrote:
> Spiro Trikaliotis wrote:
> > So, my question is: Thinking of portability, which type should I use
> > here? Or is the MS compiler wrong?
> >
> > Thanks,
> > Spiro.

>
>
> ptrdiff_t


And remember to #include <stddef.h>

--
BR, Vladimir

 
Reply With Quote
 
Spiro Trikaliotis
Guest
Posts: n/a
 
      02-23-2006
Hello pemo, Vladimir,

pemo <(E-Mail Removed)> schrieb:

> ptrdiff_t


Oh, yes. How could I forget about this one?

Thank you very much both,
Spiro.

--
Spiro R. Trikaliotis http://cbm4win.sf.net/
http://www.trikaliotis.net/ http://www.viceteam.org/
 
Reply With Quote
 
Alex Fraser
Guest
Posts: n/a
 
      02-23-2006
"Spiro Trikaliotis" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> I have a question regarding subtracting a pointer from another one.
> Assume I have two pointers p1 and p2, which both point to a memory area
> obtained with malloc(). Assume p1 = p2 + some value c.
>
> Now, I want to obtain the difference between the two, that is, the value
> c. Which type must I use for c?


The result of (p1 - p2) has type ptrdiff_t, but size_t must be able to
represent this value, since the situation guarantees it is non-negative and
less than or equal to the size (a value of type size_t) passed to malloc().

In my experience, the guarantee above is normally the case, and often the
value is compared with a size_t value, so size_t makes sense to me.

Alex


 
Reply With Quote
 
stathis gotsis
Guest
Posts: n/a
 
      02-23-2006
"Vladimir S. Oka" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) oups.com...
>
> pemo wrote:
> > Spiro Trikaliotis wrote:
> > > So, my question is: Thinking of portability, which type should I use
> > > here? Or is the MS compiler wrong?
> > >
> > > Thanks,
> > > Spiro.

> >
> >
> > ptrdiff_t

>
> And remember to #include <stddef.h>


Also remember that there is no guarantee that all pointer differences are
representable as a ptrdiff_t.


 
Reply With Quote
 
Fred Kleinschmidt
Guest
Posts: n/a
 
      02-23-2006

"Alex Fraser" <(E-Mail Removed)> wrote in message
news(E-Mail Removed)...
> "Spiro Trikaliotis" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> I have a question regarding subtracting a pointer from another one.
>> Assume I have two pointers p1 and p2, which both point to a memory area
>> obtained with malloc(). Assume p1 = p2 + some value c.
>>
>> Now, I want to obtain the difference between the two, that is, the value
>> c. Which type must I use for c?

>
> The result of (p1 - p2) has type ptrdiff_t, but size_t must be able to
> represent this value, since the situation guarantees it is non-negative
> and
> less than or equal to the size (a value of type size_t) passed to
> malloc().
>


No, there is no guarantee that (p1-p2) is non-negative.
The OP stated " Assume p1 = p2 + some value c"
He did NOT say that c was positive; as far as we know, it could very well be
negative.

> In my experience, the guarantee above is normally the case, and often the
> value is compared with a size_t value, so size_t makes sense to me.
>
> Alex
>
>

--
Fred L. Kleinschmidt
Boeing Associate Technical Fellow
Technical Architect, Software Reuse Project


 
Reply With Quote
 
Richard G. Riley
Guest
Posts: n/a
 
      02-23-2006
On 2006-02-23, stathis gotsis <(E-Mail Removed)> wrote:
> "Vladimir S. Oka" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed) oups.com...
>>
>> pemo wrote:
>> > Spiro Trikaliotis wrote:
>> > > So, my question is: Thinking of portability, which type should I use
>> > > here? Or is the MS compiler wrong?
>> > >
>> > > Thanks,
>> > > Spiro.
>> >
>> >
>> > ptrdiff_t

>>
>> And remember to #include <stddef.h>

>
> Also remember that there is no guarantee that all pointer differences are
> representable as a ptrdiff_t.
>
>


What would you use then?


--
Remove evomer to reply
 
Reply With Quote
 
Jordan Abel
Guest
Posts: n/a
 
      02-23-2006
On 2006-02-23, Richard G. Riley <(E-Mail Removed)> wrote:
> On 2006-02-23, stathis gotsis <(E-Mail Removed)> wrote:
>> "Vladimir S. Oka" <(E-Mail Removed)> wrote in message
>> news:(E-Mail Removed) oups.com...
>>>
>>> pemo wrote:
>>> > Spiro Trikaliotis wrote:
>>> > > So, my question is: Thinking of portability, which type should I use
>>> > > here? Or is the MS compiler wrong?
>>> > >
>>> > > Thanks,
>>> > > Spiro.
>>> >
>>> >
>>> > ptrdiff_t
>>>
>>> And remember to #include <stddef.h>

>>
>> Also remember that there is no guarantee that all pointer differences are
>> representable as a ptrdiff_t.
>>
>>

>
> What would you use then?


Still ptrdiff_t - if it's not representable it'll mess up before you get
to it, since the type of the expression p2-p1 (given that both p1 and p2
are pointers to the same type, of course) is ptrdiff_t.
 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      02-23-2006
Richard G. Riley wrote:
>
> On 2006-02-23, stathis gotsis <(E-Mail Removed)> wrote:
> > "Vladimir S. Oka" <(E-Mail Removed)> wrote in message


> > Also remember that there is no guarantee
> > that all pointer differences are
> > representable as a ptrdiff_t.
> >
> >

>
> What would you use then?


I believe that in a conforming program
which doesn't excede minimum environmental limits,
you're OK with ptrdiff_t, in C99.

I wrote some heapsort and quicksort functions,
that had a part that calculated a pointer difference.
I felt like making them more robust,
so I rewrote them with pointers and size_t offsets.

/* pointier version */
void q_sort(void *base, size_t nmemb, size_t size,
int (*compar)(const void*, const void*))
{
unsigned char *left, *middle, *last, *right;
size_t nmemb_right;
unsigned char *p1, *p2, *end, swap;

left = base;
while (nmemb-- > 1) {
right = left + nmemb * size;
last = middle = left;
do {
middle += size;
if (compar(left, middle) > 0) {
last += size;
BYTE_SWAP(middle, last);
}
} while (middle != right);
BYTE_SWAP(left, last);
nmemb = (last - left) / size;
nmemb_right = (right - last) / size;
if (nmemb_right > nmemb) {
q_sort(left, nmemb, size, compar);
left = last + size;
nmemb = nmemb_right;
} else {
q_sort(last + size, nmemb_right, size, compar);
}
}
}

/* size_t offset version */
void q_sort(void *base, size_t nmemb, size_t size,
int (*compar)(const void*, const void*))
{
unsigned char *left;
size_t nmemb_right, middle, last, right;
unsigned char *p1, *p2, *end, swap;

left = base;
while (nmemb-- > 1) {
right = nmemb * size;
last = middle = 0;
do {
middle += size;
if (compar(left, left + middle) > 0) {
last += size;
BYTE_SWAP(left + middle, left + last);
}
} while (middle != right);
BYTE_SWAP(left, left + last);
nmemb = last / size;
nmemb_right = (right - last) / size;
if (nmemb_right > nmemb) {
q_sort(left, nmemb, size, compar);
left += last + size;
nmemb = nmemb_right;
} else {
q_sort(left + last + size, nmemb_right, size, compar);
}
}
}

#define BYTE_SWAP(A, B) \
{ \
p1 = (A); \
p2 = (B); \
end = p2 + size; \
do { \
swap = *p1; \
*p1++ = *p2; \
*p2++ = swap; \
} while (p2 != end); \
}

--
pete
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
AddDays exception when subtracting value patrick ASP .Net 2 12-23-2005 06:09 PM
subtracting days from date =?Utf-8?B?TWFubnkgQ2hvaGFu?= ASP .Net 5 11-09-2004 01:25 AM
Subtracting large numbers usng linked list simpleman C++ 8 10-26-2004 07:36 AM
Subtracting dates Stevens Java 2 05-02-2004 06:44 AM
subtracting two dates to get number of days between Brian Henry ASP .Net 6 11-19-2003 09:50 PM



Advertisments