DL-902
DL-902

Reputation: 21

Type casting pointer dereference

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)) 
  1. Am I correctly calling this a type casting pointer dereference?
  2. It types casts addr and then derefences it? Or the other way around? Does it matter?
  3. Does order matter for type qualifiers and type specifiers? I had assumed (before this) type qualifiers had to precede type specifiers, but that must not be the case
  4. Syntax question. What's the purpose of the 2nd * ?

Upvotes: 2

Views: 816

Answers (2)

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

haccks
haccks

Reputation: 106012

  1. Am I correctly calling this a type casting pointer dereference?

Yes.

  1. 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.

  1. 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

Related Questions