As a programmer, what do I need to worry about when moving to 64-bit windows?

jm. picture jm. · Feb 13, 2009 · Viewed 11.7k times · Source

Most of my recent programming has been on 32-bit Windows using C/C++/C#/VB6 . Lately, my customers are asking if my code will run on 64-bit Windows.

I'm wondering what legacy features I might be using that will break on 64-bit Windows? What are some real-world issues I need to think about and worry about?

Obviously, I will test my code on the 64-bit OS, but I'd like to know what common issues to look for. I more concerned with the existing binaries, but I am open to comments about what to worry about when recompiling (where possible).

EDIT: Here is a nice list of 64-bit porting bugs.

Answer

bk1e picture bk1e · Feb 13, 2009

As far as I'm concerned, the single most important thing about porting C/C++ code to 64-bit Windows is to test your application with MEM_TOP_DOWN allocations enabled (AllocationPreference registry value) as described in 4-Gigabyte Tuning:

To force allocations to allocate from higher addresses before lower addresses for testing purposes, specify MEM_TOP_DOWN when calling VirtualAlloc or set the following registry value to 0x100000:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management\AllocationPreference

When does this matter?

  • If you have existing 32-bit EXEs that were built with the /LARGEADDRESSAWARE MSVC linker option (or which have the IMAGE_FILE_LARGE_ADDRESS_AWARE flag set in their PE headers through other means, such as editbin.exe), then they get a full 4 GB of virtual address space in 64-bit Windows, and you must test them with the AllocationPreference registry value set.
  • If you have existing 32-bit DLLs that may be loaded by large address aware EXEs, you must test them with the AllocationPreference registry value set.
  • If you recompile your C/C++ code into a 64-bit EXE or DLL, you must test it with the AllocationPreference registry value set.

If your C/C++ application falls into one of these three categories and you don't test with MEM_TOP_DOWN allocations, testing is very unlikely to catch any pointer truncation/signedness bugs in your code.

The second most important thing, if you use MSVC and you are recompiling C/C++ code for 64-bit, is to use the /Wp64 compiler option for your 64-bit build:

  • This will cause the compiler to emit warnings for typecasts that truncate pointers or extend smaller integral types into pointers (even when reinterpret_cast or a C-style cast is used), as well as a few other 64-bit porting issues.
  • Yes, the documentation says that instead of compiling with /Wp64 you should use a compiler that targets a 64-bit platform, but that alone will not catch pointer truncation/extension issues at compile time. Using a compiler that targets 64-bit and enabling the /Wp64 compiler option for the 64-bit build will catch many pointer truncation/extension issues at compile time, and this will save you time in the long run.
  • Unfortunately, with MSVC 2008, this will also produce a "command line warning" for each translation unit saying that the /Wp64 option is deprecated. I can see why the option is deprecated for 32-bit builds (where it is an evil hack that requires annotating many of your typedefs), but it's unfortunate that it is also deprecated for 64-bit builds (where it is actually useful).