问题描述:

#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: (type)sub-expression casts sub-expression to type type.

Your example, *(unsigned char volatile *)(0x1003) is composed of 2 sub-expressions:

  • a "lonely" star: *
  • a cast: (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 0x1003 and 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.

相关阅读:
Top