Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Where do pointers point to?

Reply
Thread Tools

Where do pointers point to?

 
 
x-pander
Guest
Posts: n/a
 
      01-12-2005
Is is guaranteed, that a pointer to any object in C points exactly at the
lowest addressed byte of this object?

Specifcally is it possible for any platform/os/compiler combination that:
(char *)v != (void *)v
where v is an int variable for example.

If so, any real-life examples?



 
Reply With Quote
 
 
 
 
Ben Pfaff
Guest
Posts: n/a
 
      01-12-2005
"x-pander" <(E-Mail Removed)> writes:

> Is is guaranteed, that a pointer to any object in C points exactly at the
> lowest addressed byte of this object?


Yes, as far as I know. (I'd love to hear intelligent
disagreement on this, because I'd learn from it.)

> Specifcally is it possible for any platform/os/compiler combination that:
> (char *)v != (void *)v
> where v is an int variable for example.


Non sequitur: you just dragged in integer-to-pointer conversion,
which is definitely non-portable.
--
"Give me a couple of years and a large research grant,
and I'll give you a receipt." --Richard Heathfield
 
Reply With Quote
 
 
 
 
x-pander
Guest
Posts: n/a
 
      01-12-2005
> Specifcally is it possible for any platform/os/compiler combination that:
> (char *)v != (void *)v
> where v is an int variable for example.


CORRECTION, of course (!!!) i meant:
(char *)&v != (void *)&v


 
Reply With Quote
 
Christian Bau
Guest
Posts: n/a
 
      01-12-2005
In article <cs1rtm$1irl$(E-Mail Removed)>,
"x-pander" <(E-Mail Removed)> wrote:

> Is is guaranteed, that a pointer to any object in C points exactly at the
> lowest addressed byte of this object?
>
> Specifcally is it possible for any platform/os/compiler combination that:
> (char *)v != (void *)v
> where v is an int variable for example.


A pointer points to the whole object.

If you cast a pointer to another type, lets say from double* to int*,
you get a pointer to an object that starts at the same place as the
first object. So if you cast a pointer to char*, it points to the first
byte of the object.

You cannot compare char* and void*. In your example, the compiler will
convert the (void *) v automatically to char*, so you are actually
comparing

(char *)v == (char *) (void *) v

which is guaranteed to be equal.
 
Reply With Quote
 
Christian Bau
Guest
Posts: n/a
 
      01-12-2005
In article <(E-Mail Removed)>,
Ben Pfaff <(E-Mail Removed)> wrote:

> "x-pander" <(E-Mail Removed)> writes:
>
> > Is is guaranteed, that a pointer to any object in C points exactly at the
> > lowest addressed byte of this object?

>
> Yes, as far as I know. (I'd love to hear intelligent
> disagreement on this, because I'd learn from it.)


It points to the "first" byte. The C Standard doesn't say anything about
addresses.

So if you have

int x;
char* p = (char *) &x;

then the bytes of x are p [0], p [1], ..., p [sizeof (int) - 1], and not
for example p [0], p [-1], p [-2] and so on.

However, imagine you have an application of 10 million lines of code,
non-portable because it is written under the assumption that your
hardware is bigendian. You need to make it run on littleendian hardware.
You have the source code to the compiler. Instead of changing 10 million
lines of code, change the compiler so that the "first" byte is at a
higher address than the last byte; where "p++;" would usually be
translated into a hardware instruction that adds sizeof (*p), it will be
translated to a hardware instruction that subtracts sizeof (*p). Pointer
comparisons say that p < q if a hardware compare instruction says p > q
and so on. Now a pointer always points to the highest addressed byte,
and it is completely conforming and invisible to the programmer. The
compiler turned a littleendian hardware into a bigendian implementation.
(Code that casts pointers to unsigned int and checks the last bits for
alignment will not work anymore; casting to and from integer will
generally give strange results).
 
Reply With Quote
 
x-pander
Guest
Posts: n/a
 
      01-12-2005
> If you cast a pointer to another type, lets say from double* to int*,
> you get a pointer to an object that starts at the same place as the
> first object. So if you cast a pointer to char*, it points to the first
> byte of the object.


I undesrtand that.

> You cannot compare char* and void*. In your example, the compiler will
> convert the (void *) v automatically to char*, so you are actually
> comparing
>
> (char *)v == (char *) (void *) v
>
> which is guaranteed to be equal.


So how about the result of the following comparision,
which i think has a potential of effectively answering my original question:

(int *)(char *)&v != &v




 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      01-12-2005
Christian Bau <(E-Mail Removed)> writes:
> In article <(E-Mail Removed)>,
> Ben Pfaff <(E-Mail Removed)> wrote:
>
>> "x-pander" <(E-Mail Removed)> writes:
>>
>> > Is is guaranteed, that a pointer to any object in C points exactly at the
>> > lowest addressed byte of this object?

>>
>> Yes, as far as I know. (I'd love to hear intelligent
>> disagreement on this, because I'd learn from it.)

>
> It points to the "first" byte. The C Standard doesn't say anything about
> addresses.


Sure it does. Just one example, C99 6.5.3.1p3:

The unary & operator returns the address of its operand.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <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.
 
Reply With Quote
 
x-pander
Guest
Posts: n/a
 
      01-12-2005
> It points to the "first" byte. The C Standard doesn't say anything about
> addresses.


Actually it does:
C99: 6.3.2.3.7
"When a pointer to an object is converted to a pointer to a character type,
the result points to the lowest addressed byte of the object. Successive
increments of the result, up to the size of the object, yield pointers to
the remaining bytes of the object."

> You need to make it run on littleendian hardware.
> You have the source code to the compiler. Instead of changing 10 million
> lines of code, change the compiler so that the "first" byte is at a
> higher address than the last byte; where "p++;" would usually be
> translated into a hardware instruction that adds sizeof (*p), it will be
> translated to a hardware instruction that subtracts sizeof (*p). Pointer
> comparisons say that p < q if a hardware compare instruction says p > q
> and so on. Now a pointer always points to the highest addressed byte,
> and it is completely conforming and invisible to the programmer.


An example situation in described system could be:

int x;
&x == 0x4003
(void *)&x == 0x4003
(char *)&x == 0x4000
(void *)(char *)&x = 0x4000

So:
(void *)&x != (void *)(char *)&x

In effect the following code would break (i've seen similar code in some
libraries):

void zero(void *ptr, int size)
{
memset(ptr, 0, size);
}
main()
{
int v;
zero(&v, sizeof(v));
}

The solution is to always use char * instead of void *.

Am I right?


 
Reply With Quote
 
x-pander
Guest
Posts: n/a
 
      01-12-2005
> It points to the "first" byte. The C Standard doesn't say anything about
> addresses.


Actually it does:
C99: 6.3.2.3.7
"When a pointer to an object is converted to a pointer to a character type,
the result points to the lowest addressed byte of the object. Successive
increments of the result, up to the size of the object, yield pointers to
the remaining bytes of the object."

> You need to make it run on littleendian hardware.
> You have the source code to the compiler. Instead of changing 10 million
> lines of code, change the compiler so that the "first" byte is at a
> higher address than the last byte; where "p++;" would usually be
> translated into a hardware instruction that adds sizeof (*p), it will be
> translated to a hardware instruction that subtracts sizeof (*p). Pointer
> comparisons say that p < q if a hardware compare instruction says p > q
> and so on. Now a pointer always points to the highest addressed byte,
> and it is completely conforming and invisible to the programmer.


An example situation in described system could be:

int x;
&x == 0x4003
(void *)&x == 0x4003
(char *)&x == 0x4000
(void *)(char *)&x = 0x4000

So:
(void *)&x != (void *)(char *)&x

In effect the following code would break (i've seen similar code in some
libraries):

void zero(void *ptr, int size)
{
memset(ptr, 0, size);
}
main()
{
int v;
zero(&v, sizeof(v));
}

The solution is to always use char * instead of void *.

Am I right?



 
Reply With Quote
 
italy
Guest
Posts: n/a
 
      01-12-2005
You're cute, Ben Pfaff!

 
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
Share-Point-2010 ,Share-Point -2010 Training , Share-point-2010Hyderabad , Share-point-2010 Institute Saraswati lakki ASP .Net 0 01-06-2012 06:39 AM
pointers, pointers, pointers... cerr C Programming 12 04-07-2011 11:17 PM
Scenario 5: IS-IS routing on Frame Relay Multi-point and Point-to-Point David Sudjiman Cisco 0 06-08-2006 09:11 AM
pointers to pointers // exception handling error muser C++ 3 09-18-2003 06:19 PM
Template specialization of pointers with function pointers Phil C++ 1 09-16-2003 02:17 AM



Advertisments