#define PORTC *(unsigned char volatile *)(0x1003)
#define DDRC *(unsigned char volatile *)(0x1007)
So I've been trying to read some stuff about embedded C. Initially I thought this macro was a pointer-to-pointer type but then I soon assumed the last star is actually a dereference rather than a type-cast, am I correct? Dereferencing to the location 0x1003/0x1007.
It is used like:
PORTC = <some hex value>
Question is what makes this different from a pointer type-cast? Is there some sort of 'provision' in the C specifications? Or am I just an idiot...
Also I don't quite know how to phrase this and so I couldn't do a quick search first...
It's just the way the C grammar is defined.
To be a cast, the expression needs parenthesis:
sub-expression to type
*(unsigned char volatile *)(0x1003) is composed of 2 sub-expressions:
(unsigned char volatile *)(0x1003)
The cast is composed of the type inside
() and a value.
So, the whole expression is interpreted as a pointer, then de-referenced to set the memory area pointed to.
No, it is quite a cast.
First, the memory location (as integer) is cast into an appropriate pointer which is then dereferenced.
That code is basically equivalent to: Put
<some hex value> in the memory at the address (0x1003) (or whatever the value is). In some embedded devices (and not only) ports are mapped at memory locations.
The cast instructs the compiler that the memory addresses
0x1007 are to be treated as
unsigned char volatile * pointers, and the
* dereferencing operator acts on that pointer to fetch the pointed-to value, which in this case is 1 byte.
Applying the unary
* makes this expression a valid lvalue (it wouldn't be so without it) which means that it is something you can assign to.