A major driver of modern C/C++ development is the need for producing native 64-bit code. In most cases, servers and desktop systems are now almost exclusively 64-bit machines. Given this fact, isn't the move to 64-bit C/C++ code just a matter of changing a few build settings? Stephen B. Morris explains why it's not so simple.

Like this article? We recommend

Migrating 32-bit C/C++ code to 64-bit is not a trivial task. There are many issues to consider. This article looks at the areas of numerical limits, data alignment, pointer arithmetic, and array indexing. Before getting underway, let's take a short detour to provide some definitions, starting with the term “64-bit” itself.

NOTE

Most of the code examples for this article are pretty simple, but a zip file is available for download.

Just What Exactly Is '64-Bit'?

x86-64 (also known as x64, x86_64, and AMD64) is the 64-bit version of the instruction set for . It's easy to find out if your system is 64-bit or not. On Linux, just type the following terminal command:

Notice the presence of the x86_64 symbol. If you see output similar to this, then you have a 64-bit machine; that is, the architecture is x86-64. If you have a 32-bit platform, you'll likely see something similar, except for a string such as i686 i386 GNU/Linux.

Notice that I'm using a virtual machine running Ubuntu. This is a really convenient way to experiment with different architectures: You simply create a virtual machine using VirtualBox or VMware, install an appropriate operating system, configure it, and away you go. If your development platform supports it, you can play around with a 64-bit system simply by creating a virtual machine.

A 64-bit processor supports considerably larger amounts of virtual memory and physical memory than is possible on 32-bit architectures. This is one of the major benefits of 64-bit, because it allows programs to store large amounts of data in memory. In addition, x86-64 provides 64-bit general-purpose registers and a variety of other enhancements, such as a more resilient memory model.

x86-64 is also fully backward compatible with 16-bit and 32-bit x86 code. This compatibility is really important because it allows existing or legacy 32-bit binaries to run with no compatibility or performance penalties. It sounds just perfect, being able to run 32-bit and 64-bit code on the same machine, right?

Compatibility Mode

As mentioned previously, running 32-bit C/C++ binary code is not generally an issue on modern 64-bit machines, thanks to various compatibility solutions; for example, Windows has Wow64. Linux also allows 32-bit legacy code to run. However, as with any technology, there's never a free lunch! 32-bit code running in compatibility mode may in fact be slower than a native 64-bit version. On the plus side, such 32-bit code may have access to more memory when running on a 64-bit machine.

For applications running on Windows, the legacy 32-bit code may well need access to DLLs, which also must be 32-bit versions. The same issue applies for Linux binaries that use external 32-bit libraries.

What this means is that it's entirely feasible to run 32-bit code on the 64-bit platform; however, the external libraries may have to be separately installed and maintained. Supporting multiple library versions can be a pain, particularly if the host machine is not under your control (for instance, on a customer machine).

As you see, using 32-bit C/C++ in a 64-bit world has a price tag attachednot a big price, but it must be paid, and the longer you stay with 32-bit code, the more it costs. Why is this?

End-User Perception

In addition to the hassles you suffer by staying with 32-bit code, your customers and users may not be so happy using what they might begin to think of as “legacy” technology. Of course, this concern is probably more psychological than real, but some customers may come to see your continuing use of 32-bit code as them doing you a favor, and they might look for something in return for putting up with that pesky 32-bit code. For example, they might request extra features from your software. Developing those extra features could ultimately take your effort away from porting to 64-bit code. In effect, this issue of 32-bit versus 64-bit code could become a significant cost to your organization.

So, in summary, it is possible to maintain your 32-bit C++ code and keep running with it in the 64-bit world. However, as we now know, it's not without difficulties. Beyond these logistical issues, are there other reasons for moving to 64-bit C++? Good question.