# HIWORD and LOWORD macros

• 12-05-2008
kalevi
HIWORD and LOWORD macros
I have seen the HIWORD and LOWORD in some winapi header file. As their name suggests they select the higher or lower WORD (16bit) from a DWORD(32bit). Whats the function of the '& 0xFFFF' in the definition of the HIWORD macro? I know what it does, but for me, it seems pointless. The right shift leaves 0s in the higher 16bits anyway, so whats the point in masking them out?

Simple test program:
Code:

```#include <stdio.h> typedef unsigned long DWORD; typedef unsigned short WORD; #define LOWORD(a) ((WORD)(a)) #define HIWORD(a) ((WORD)(((DWORD)(a) >> 16) & 0xFFFF)) int main() {         DWORD d=0xABCD1234;         printf("Original value:\n");         printf("      d  == %X\n",d);         printf("\nMacros:\n");         printf("LOWORD(d) == %X\n", LOWORD(d));         printf("HIWORD(d) == %X\n", HIWORD(d));         printf("\nSimple hiword:\n");         printf("  d >> 16 == %X\n", d >> 16);                         return 0; }```
• 12-05-2008
tabstop
Because the right shift may or may not leave zeroes. Try shifting -1 >> 16 and see what happens.
• 12-05-2008
kalevi
...
As I understand right shift does sign extension, thus signed negative numbers leave 1s, signed positive and unsigned numbers leave 0s in the upper bits.

Some test code:
Code:

```#include <stdio.h> typedef unsigned long DWORD; typedef unsigned short WORD; #define LOWORD(a) ((WORD)(a)) #define HIWORD(a) ((WORD)(((DWORD)(a) >> 16) & 0xFFFF)) int main() {         int a=-1; // signed numbers are stored in two's complement, so this equals 0xFFFFFFFF         printf("a >> 16            == &#37;X\n",a >> 16); // FFFFFFFF         printf("(DWORD)(a) >> 16  == %X\n",(DWORD)(a) >> 16); //FFFF         printf("\n");                         a=0xABCD1234;         //upper bits are sign extended -> int a : signed         printf("a >> 16            == %X\n",a >> 16); // FFFFABCD                 //no sign extension -> (DWORD) is an unsigned cast         printf("(DWORD)(a) >> 16  == %X\n",(DWORD)(a) >> 16); //ABCD         return 0; }```
For me it seems that there is still no need for a mask, because there is an unsigned cast in the macro definition: (DWORD)(a). So, why the need for the mask '& 0xFFFF' when we already have an unsigned cast?
• 12-05-2008
tabstop
I didn't notice the cast. So someone was probably just being paranoid.
• 12-05-2008
kalevi
Its good to know I don't miss anything there. Thanks for the help!
• 12-06-2008
Elysia
Or they wanted to be sure that they could stuff that into a WORD without warnings.
• 12-06-2008
matsp
Also, if you use the and at the end of such an operation, most optimizing compilers will "know" if it actually needs to perform the and operation or not - and thus it's not actually causing a problem to perform the and when it's not needed. If you then port the code to a machine which can't do this without using an and, it will still work.

Just because something works with one or two compilers on one or two types of machine, doesn't necessarily mean that it will work in ALL compilers or ALL processor architectures. Belts and braces.

--
Mats
• 12-06-2008
kalevi
So, the AND part makes the macro more robust. By the way, -out of curiosity- do you know cases (arch/os/compiler) where the code without the '& 0xffff' would not work?

Furthermore, how should I code in a platform/compiler independent manner? Any guide, book or tutorial on that?

• 12-07-2008
matsp
Quote:

Originally Posted by kalevi
So, the AND part makes the macro more robust. By the way, -out of curiosity- do you know cases (arch/os/compiler) where the code without the '& 0xffff' would not work?

Furthermore, how should I code in a platform/compiler independent manner? Any guide, book or tutorial on that?