Home > Guides > Programming > C/C++

Migrating to 64-Bit Environments

Created Apr 11, 2003.

32-bit architectures will remain predominant in the near future. However, developers should bear in mind that their applications may sooner or later be ported to 64-bit environments, as these are becoming increasingly widespread. In this article, I discuss the ramifications of migrating to 64-bit environments and explain the major differences between the object models of these two environments.

Compatibility Issues

The good news is that, in the majority of cases, migrating your 32-bit apps to a 64-bit environment should be simple. All that it would take is recompilation and re-linking. In practice, however, a few issues need special attention.

When speaking of portability of C++ code, one usually means source file portability. By contrast, the binaries are rarely portable even among different compilers on the same platform. Porting 32-bit code to a 64-bit environment means that there could be substantial differences between the binaries produced from the same source file under the two environments. Let's look at some of these differences more closely.

Built-in Types

C++ programmers who started their career in the DOS heyday learned to use long whenever they needed a 32-bit integer. However, in certain 64-bit systems long is now a 64-bit integer. If your code depends on the actual number of bits that a datatype occupies, you should use the standard typedef names:

//defined in the C99 <inttypes.h> 
int8_t   int16_t   int32_t   int64_t 
uint8_t   uint16_t   uint32_t   uint64_t 

Unfortunately, these typedefs are defined by C99 but not by ISO C++. In practice, however, most C++ compilers support C99 extensions including <inttypes.h>. Alternatively, you may define your own typedef names and use conditional compilation to ensure platform-independence.

Another problem that may arise is that new processors sometimes don't support 8-bit types at all. C++ requires that the smallest addressable datatype should be char. Such platforms represent char as a 16-bit type. Again, if the underlying number of bytes is not an issue, you can safely ignore this difference since all the standard char * functions and data structures will work as expected. If you truly need an 8-bit datatype, you have to use bit fields or other kludges. Should that be the case, it's always advisable to hide the low-level details in a class such as std::bistet or a similar custom class.

Pointers

32-bit systems represent data pointers as a 32-bit integer. 64-bit systems have 64 bit pointers in addition to, or instead of, 32-bit pointers. This duality enables users to run 32-bit programs under an emulator. Ideally, however, programs should use the default addressing mode which relies on 64-bit pointers. This difference affects pointers to freestanding functions as well.

Pointers to members are a different story, though. Under 32-bit architectures, they may have various sizes, depending on compiler settings, the member function in question and their class's inheritance lattice. In most cases, a typical pointer to member is represented as a struct that packs two ordinary pointers. This means that under a 64-bit system a typical pointer to member will have twice as many bits compared to its 32-bit counterpart. There could also be differences with respect to the actual values of pointers to members due to the alignment scheme of 64-bit environments.

Member Alignment

Member alignment is affected by the addressing mode of the target platform, the hardware's alignment requirements and compiler switches. In 64-bit systems you should expect a quadword (8 bytes or 64 bits) alignment scheme or higher, as opposed to the typical dword (4 bytes) alignment of 32-bit systems. Consequently, the sizes of user-defined types i.e., structs, classes, unions and enumerations could increase due the extra padding bytes inserted between members.

ABI

A platform's ABI defines a binary protocol for naming symbols and other layout issues. These symbols include the decorated names of functions, external objects, static data members and so on. The decorated names of functions with C++ linkage encode, among other things, their parameter types and their stack offset. Because the parameters' size may change when migrating to a 64-bit environment, the decorated names of functions, member functions, templates, structs, classes and so on may change accordingly.

Let's look at a concrete example:

struct S
{
void * p; // 4/8 bytes under 32/64 bit systems
int n; // 4 bytes
}; //sizeof (S)==8/16 under 32/64 bit envs, respectively
void func (S& );

The decorated name produced by a 32-bit compiler for the function func() could look like this:

v__func@@struct_S8@

A 64-bit compiler may produce this decorated name instead:

v__func@@struct_S16@

This difference eliminates the risk of inadvertently linking incompatible binaries. However, it also means that if you have a library or a dll only as a binary file, you will have to get an updated 64-bit version thereof. Tools that convert pure .exe and other binary formats are available on some 64-bit platforms. However, the best solution is to recompile the original source files.

Summary

The advent of 64-bit systems demonstrates once more the importance of separating low-level, platform dependent implementation details from the interface. Code that doesn't rely on hard-coded magic numbers and specific sizes of datatypes is easier to port. Therefore, even if the migration to a 64-bit environment still seems remote, it's best to design your new apps so that this migration would be as smooth and automatic as possible, necessitating only recompilation and re-linking.

Discussions

Bugzilla
Posted Nov 18, 2008 01:53 AM by cupu
2 Replies
auto_ptr issues
Posted Sep 14, 2007 07:43 AM by singh_siddhu
1 Replies
i want c++ book through net
Posted Aug 23, 2007 11:13 PM by harivilu
3 Replies

Make a New Comment

You must log in in order to post a comment.

Related Resources

Danny KalevMinutes from the October 2009 Meeting
By Danny KalevNovember 19, 2009 No Comments

The minutes from the Santa Cruz (October 2009) meeting are available here. Even if you're not a language layer at heart, I encourage you to read them.

Danny KalevA Reader's Opinion on Attributes
By Danny KalevOctober 20, 2009 No Comments

In August I dedicated a series to the debate about C++0x attributes. I believe that it covered the subject in a balanced and detailed way, but I keep getting complaints from C++ users who don't like attributes for various reasons. Here's a recent email I received from a Polish C++ programmer. While it  doesn't represent my opinion about attributes -- I'm rather neutral about this feature and consider it a "solution waiting for a problem" -- but it suggests that attributes are still a highly controversial issue that will haunt C++ for a long time. The email is quoted here with minor edits that and as usual, with all private details removed.

Danny KalevFollowup: The Web 2.0 Guy I Ain't
By Danny KalevOctober 16, 2009 1 Comment

Almost a year ago, I posted here The Web 2.0 Guy I Ain't. People wonder whether I still resist all those Web 2.0 features and technologies at the end of 2009.

See More Blogs

Informit Network