Deciphering ISO C (Chap 6.3.2.3 - Pointers)

P

Philip S

Hi,

Forgive me for not searching the entire newsgroup, should this question
already have been answered..

I can't find the logic in why this example doesn't work:

unsigned short* res_16;
unsigned short* pu_16;
unsigned short u_16;

pu_16 = 0x0u;
u_16 = 0x0u;
res_16 = (pu_16 + 0x555u);

The above code yields res_16 == 0xAAA.
I was sort of hoping for 0x555 instead...

Altering the addition line to this:
res_16 = (unsigned short*)(u_16 + 0x555);
corrects the problem...

why?

The platform is a 32bit Intel.
Trying to decipher the addition, I get:
1) 32bit_u = (32bit_u + 32bit_u)
2) 32bit_u = (32bit_u)(16bit_u + 32bit_u)
assuming that the pointer "unsigned short *" is 32bit...

- Philip
 
K

Kevin P. Fleming

Philip said:
res_16 = (pu_16 + 0x555u);

The above code yields res_16 == 0xAAA.
I was sort of hoping for 0x555 instead...

No, this makes perfect sense. pu_16 is a pointer to an unsigned short,
which is a 16-bit quantity. Advancing the pointer by 0x555 items will
change the pointer's address by 0xAAA bytes.
The platform is a 32bit Intel.
Trying to decipher the addition, I get:
1) 32bit_u = (32bit_u + 32bit_u)

No, this is not right at all. The pointer is not treated as a 32bit_u in
this operation, at least not in the way you think. When the compiler
sees you adding value 'n' to a pointer, it interprets that to mean you
want make the pointer point 'n' items past where it does now. If the
pointer points to 18-byte structures (for example), then the pointer
will actually be advanced 18*n bytes.
 
K

Keith Thompson

Philip S said:
Forgive me for not searching the entire newsgroup, should this question
already have been answered..

I can't find the logic in why this example doesn't work:

unsigned short* res_16;
unsigned short* pu_16;
unsigned short u_16;

pu_16 = 0x0u;
u_16 = 0x0u;
res_16 = (pu_16 + 0x555u);

The above code yields res_16 == 0xAAA.
I was sort of hoping for 0x555 instead...

Altering the addition line to this:
res_16 = (unsigned short*)(u_16 + 0x555);
corrects the problem...

This illustrates the danger of thinking of pointers as integers.

The first assignment, "pu_16 = 0x0u;", assigns a null pointer value to
pu_16. It would be more clearly written as "pu_16 = NULL;" (assuming
"#include <stdlib.h>"). A null pointer is best thought of as a null
pointer. It may or may not be represented as all-bits-zero (it
probably is on your platform).

The expression "pu_16 + 0x555u" is an example of pointer arithmetic.
Adding an integer value N to a pointer yields a pointer that points N
elements (not necessarily bytes) after the original pointer. In this
case, if pu_16 pointed to a sufficiently large array of shorts, res_16
would point to the 0x555th (1365th) element of that array. If the
underlying pointer representation happens to look like an integer byte
index, the result will look like you added 0xAAA to it. Since pu_16
is a null pointer, you're invoking undefined behavior.

What were you planning to do with res_16 anyway? Unless you're
working on an embedded system, it's not likely that there's anything
meaningful at address 0xAAA.

See the section on pointers in your C textbook, and sections 4 and 5
of the C FAQ at <http://www.eskimo.com/~scs/C-faq/top.html>.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,534
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top