Reputation: 51
#define LODWORD(x) (*((unsigned int*)&(x)))
I'm translating C code to python and can't quite get this. If anyone can explain how to read this or what it means it'd be greatly appreciated.
Upvotes: 1
Views: 2179
Reputation: 232
First by using #define
defines a macro that does substitution. It is a macro with an argument, a so-called "function-like macro".
After the #define
when an expression LODWORD(whatever you write here)
occurs it will be replaced by (*((unsigned int*)&(whatever you write here)))
before the code is fed into the compiler. This is called "macro expansion". The compiler will only see expanded expressions.
The macro expanded expression of LODWORD(foo)
does the following:
(foo)
is common idiom in macros: Put arguments into parentheses to avoid operator precedence errors.
&(foo)
means "the address of (foo)
" (a "pointer"). This creates a value that represents the memory location of foo
. It is of type "pointer to the type of foo
" .
(unsigned int*)&(foo)
converts "the adress of foo
" into "the address of the unsigned int
foo
". The operator (insigned int*)
is called a "cast operator". It changes the result type "pointer to the type of foo
" into "pointer to an unsigned int
".
((unsigned int*)&(foo))
overrides operator precedence. Now you have "pointer to an unsigned int
at the memory location of foo
.
*((unsigned int*)&(foo))
returns the value of the unsigned int
at the memory location of foo
(even if foo
is not an unsigned integer and even if that memory location violates alignment requirements for an unsigned int
).
(*((unsigned int*)&(foo)))
is yet another common idiom in macros: Put the entire expression into parentheses to avoid operator precedence errors. Then the macro can always be used as if it was a function.
Upvotes: 0
Reputation: 3638
It's a macro for getting the lower DWORD
( 32bits ) of a 64 bit variable, there's most likely an associated HIDWORD
macro as well to get the higher 32 bits. Other comments have pointed out some flaws with the macro, but it's a fairly common idiom for accomplishing this.
Some equivalent Python code might be:
def LODWORD(x):
return x & 0xFFFFFFFF
Upvotes: 3
Reputation: 198476
&(x) // get address of `x` as a pointer to whatever x is
(unsigned int*)(...) // cast it to a pointer to `unsigned int`
*(...) // then read that address' contents as if it was `unsigned int`
I'd use union
if really needed, and only if I knew the CPU architecture, otherwise this is very very unsafe :P
Upvotes: 3