user3851290
user3851290

Reputation: 51

What does this line of code mean (Bitwise Operator)

#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

Answers (3)

N. Paul
N. Paul

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

ajxs
ajxs

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

Amadan
Amadan

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

Related Questions