Reputation: 21
Sorting through a retired engineers code and I encountered a fairly simple macro, but my C knowledge isn't great.
#define mem32(addr) (*(unsigned long volatile *)(addr))
Upvotes: 2
Views: 816
Reputation: 40625
The cast (unsigned long volatile *)(addr)
happens before the dereferencing.
And no, the order of the words unsigned
, long
, and volatile
does not matter as long as no further operators are mixed in. I. e. volatile int*
and int volatile*
are the same, but int * volatile
is something different.
On a high level, the purpose of this macro is to take any pointer, and read the first four bytes from that memory address.
However, this invokes undefined behavior if the pointer that's passed to mem32
is neither a pointer to long
or char
! This is due to strict aliasing rules. Older compilers used to safely generate the intended code for this macro, but modern compilers may just optimize the code using that macro away if they prove a type mismatch. So, don't use this in new code.
Upvotes: 1
Reputation: 106012
- Am I correctly calling this a type casting pointer dereference?
Yes.
- It types casts addr and then derefences it? Or the other way around? Does it matter?
The *(unsigned long volatile *)(addr)
is typecasting addr
and then dereferencing it.
- Does order matter for type qualifiers and type specifiers?
No. Order doesn't matter. C11 section §6.7.2/2
[...] the type specifiers may occur in any order, possibly intermixed with the other declaration specifiers. [...]
Upvotes: 1