Ivan Gotovchits said:
Please, help me with the pointers.
I've a base pointer, say it is a 0x06000000 and offsets from it to
registers (for example, #define REG1 0x04). I'm accessing to them in a
following way.
void *base = MEMBASE; /* 0x06000000 */
uint32_t val = 0;
val = ((uint32_t) *(base + REG1));
/* do something with val */
((uint32_t) *(base + REG1)) = val;
Is this code correct?
No, it's not. The code performs arithmetic on a void *, which is not legal
C. Furthermore, the result of a cast is not a modifiable lvalue, so it
cannot be the left operand of an assignment statement.
I'm not sure because sizeof(void *) = 4, so (base +
4) will be (base + 4 * (sizeof(void *))),
No, even if sizeof(void *) is 4, this is of no consequence to the
expression (base + 4). When you add N to P (where P is a pointer to some
object type), the result is a pointer value that points N objects past P,
where the size of the object is determined by computing the size of the
kind of object to which P points. Since one cannot take the size of such
an object when P is of type void *, the calculation is illegal.
that will point me to the
incorrect address. If it is true, then what will be the correct method?
Well, there isn't a "correct" method, but there are less incorrect methods!
That is, the C Standard doesn't make any guarantees about what will happen
when you do the following:
#define MEMBASE (void *)0x06000000UL
void *base = MEMBASE; /* 0x06000000 */
unsigned char *ucbase = base;
uint32_t val = 0;
val = *(uint32_t)(ucbase + REG1);
/* do something with val */
*(uint32_t)(base + REG1) = val;
but it does at least have a fighting chance of working as you expect on
*some* (but by no means all) implementations.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999