Typical error porting application from 32- to 64-bit

I recently ran across a bug with an application ported to the x64 platform. After debugging the application the error turned to be due to integrals layout and casting. I think this is a typical example worth mentioning.

It starts with this definition:

which is used for a combo box with SetItemData:

Notice the cast to DWORD, which is an integral type represented on 32-bits both on x86 and x64. At a later point this value was retrieved and tested against COMBO_VALUE:

They key here is how the value of -99 is represented:

  32-bit platform 64-bit platform
-99 FFFFFF9D FFFFFFFFFFFFFF9D
(DWORD)-99 FFFFFF9D FFFFFF9D
(DWORD_PTR)-99 FFFFFF9D FFFFFFFFFFFFFF9D
(DWORD_PTR)(DWORD)-99 FFFFFF9D 00000000FFFFFF9D

GetItemData returns a DWORD_PTR, so FFFFFF9D becomes 00000000FFFFFF9D on x64. Then -99 is also interpreted as a DWORD. Thus the condition in the above if statement resolves to 00000000FFFFFF9D == FFFFFFFFFFFFFF9D on x64, which of course is false.

To fix the problem, the if statement should be re-written like this:

A very simply fix, but not so simple to spot the root of the problem when just reading the code.

1 Reply to “Typical error porting application from 32- to 64-bit”

  1. I have to disagree…
    This should be the correct solution:

    pCombo->SetItemData(index, (DWORD_PTR)COMBO_VALUE);

    if (pCombo->GetItemData(pCombo->GetCurSel()) == (DWORD_PTR)COMBO_VALUE)

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.