C++Builder 64-bit Windows Differences

From RAD Studio XE3
Jump to: navigation, search

Go Up to C++Builder 64-bit Windows Application Development

This topic provides an overview of the differences between BCC64 and its immediate predecessor, BCC32. BCC64 is the latest in a long line of compilers entwined in the minutiae-laden history of C/C++ development since DOS and 16-bit Windows.

For specific steps to port your existing 32-bit C++ projects to 64-bit Windows, see Upgrading Existing C++ Projects to 64-bit Windows.

Differences Between 32-bit Windows and 64-bit Windows Applications

Moving to 64-bit development is a widely covered topic on the Internet, especially as it relates to C++ and Windows. For more information, see the following topics:

Two basic concepts are stressed here.

size_t versus unsigned

size_t is defined as an unsigned integral type, passed to malloc and the result of sizeof, with enough bits to represent the size of the largest possible object in the memory/data model. In Win32 and Win64, this is the same size as a pointer. (These modern Windows memory models are flat. In contrast, in the segmented Large memory model of DOS, pointers were 32-bit, while the largest object was 64KB. So size_t could be 16-bit.)

In Win32's "ILP32" data model, int (and long) and pointers are 32-bit. You could use unsigned int in place of size_t, although it is not portable.

Win64 is an "LLP64" data model: long long and pointers are 64-bit, while int (and long) are still 32-bit. Therefore, you must use size_t.

_WIN32 Is Defined For Win64

_WIN32 is defined (as the integer 1) for both Win32 and Win64 targets. This allows programs to target (modern) Windows in general, among other platforms.

_WIN64 is defined only for Win64 targets; because _WIN32 is also defined, check _WIN64 first, something like this:

#if _WIN64
  // 64-bit Windows
#elif _WIN32
  // 32-bit Windows
#elif __APPLE__
  // Mac OS X (or iOS, requires more detection)
  #error Not a supported platform

Compiler Differences

BCC64 is based on the Clang compiler front-end.

Compiler Options

BCC64 uses an almost completely different set of compiler options, and a different way to express multiple values for the same option.

Stricter C++ Compiler

BCC64 is more compliant with C++ language standards than BCC32.

Warnings and Error Messages

In addition to new, more specific and detailed warnings and error messages, BCC64 phrases messages for conditions detected by BCC32 in a different way.

For more information, see BCC64 Errors and Warnings.

Predefined Macros

To get all the predefined macros directly from the preprocessor, run:

echo | bcc64 -E -dM -

The -E option runs the preprocessor only. -dM dumps all macros defined during preprocessing and stops. The final - takes input from stdin, which is sent through the pipe from the empty echo.

For more information, see Predefined Macros.

Detecting BCC64

It is usually sufficient and more portable to detect Win64 by checking for _WIN64. But to detect BCC64 specifically, you can use:

#if __BORLANDC__ && __clang__

__BORLANDC__ is the compiler version (currently 0x0650 for version 6.50) and __clang__ is 1 for BCC64.

For more information, see Predefined Macros.

#include Paths and Lookup

BCC64 supports three different header/source paths:

  • -isystem is for system headers included with BCC64. Warnings for headers found on this path are suppressed.
  • -I is for headers provided by third parties.
  • -iquote is for your own source files and headers. As the name suggests, this path is used only for directives with quotes: #include "file". If the named file is not found, then the paths specified by -I and -isystem are searched, as if the directive was #include <file>

Your 64-bit Windows C++ applications should always contain:

 #include <windows.h>

With BCC32, including windows.h is not required, but BCC64 requires windows.h and is more strict about #includes. For more information, see #include.

You might need to #include headers differently with BCC64.

For example, BCC64 does not find headers specified with semi-absolute paths as BCC32 does. Given that 'myOtherFile' is located at C/myProjectsDir/myOtherApp, the following references in a .CPP file are accepted by both BCC64 and BCC32:

#include "c:/myProjectsDir/myApp/mySource.h" //absolute path, ok in BCC64 and BCC32
#include "../myApp/mySource.h" //relative path, ok in BCC64 and BCC32

However, the following yields an error from BCC64 but is accepted by BCC32:

#include "/myProjectsDir/myApp/mySource.h" //semi-absolute path: Fails in BCC64, ok in BCC32

BCC64 emits the following error:

 [bcc64 Fatal Error] myOtherFile.cpp(27): '/myProject/myApp/mySource.h' file not found

For more information, see #include.

Precompiled Headers

Compared to BCC32, precompiled headers work a little differently for BCC64. Each 64-bit Windows C++ project can have only one precompiled header, and a default precompiled header (named projectPCHn.h) is generated for each new C++ project (for any platform).

For more information, see the following topics:

Object and Library File Format

  • BCC32 and its associated tools use OMF in .obj and .lib files.
  • BCC64 uses ELF in .o and .a files.

This difference means, for example, that when you migrate a 32-bit Windows application to 64-bit Windows, you must change references to .lib and .obj files to be .a and .o, respectively.

Debugger Features

See Debugging C++Builder 64-Bit Windows Applications.

Unsupported Features

Several options and features are not supported in BCC64.

Producing 64-bit Packages Not Supported

BCC64 does not produce packages (.bpl files) in this release. You can, however, do static linking to a 64-bit Windows package, and you can consume packages using C++Builder 64-bit Windows.

Deprecated BCC32 Extensions and Keywords

No-underscore and single-underscore compiler keyword extensions are either unsupported or deprecated in BCC64. Use the double-underscore versions (they are also supported in BCC32):

  • cdecl, _cdecl:    Use __cdecl
  • pascal, _pascal:    Use __pascal
  • _fastcall:    Use __fastcall, which is now Microsoft-style, not Borland-style
  • _stdcall:    Use __stdcall
  • _fortran, __fortran:    Not supported, obsolete
  • asm, _asm, __asm:     Inline assembly is not supported
  • _export:    Use __export
  • _import:    Use __import
  • _declspec:    Use __declspec

BCC32 Attributes

See Workaround for C++0x Attributes (noreturn and final).

Unicode Identifiers

Although Unicode is supported in literal strings and file names, Unicode in identifiers is not allowed.

Inline Assembly with BCC64

For an example of inline assembly, see Inline Assembly with BCC64 (C++).

C++Builder for 64-bit Windows allows inline assembly with this caveat:

  • The assembler must use the AT&T line-by-line syntax, not the more familiar block-of-Intel syntax.
For more information, see GCC-Inline-Assembly-HOWTO

BCC64 supports inline assembly in a different style than the inline assembly supported by BCC32:

  • Different Assembly syntax: The Assembly syntax supported by BCC64 is line-by-line AT&T syntax, not the more familiar block-of-Intel syntax.
  • Potential exception handling and debugging problems: Win64’s exception handling places additional burdens on hand-written Assembly code intermixed with C++. Functions written entirely in assembly (with a separate assembler like NASM or MASM) can be linked into your BCC64 program. However, there are inherent issues (potential exception handling and debugging problems) that you should know before you start.
The reasons for these issues for inline assembly can be summarized as: pdata. For exceptions (and debugging) to work, Windows/x64 code has to generate data structures (pdata) that describe each function and what must be unwound if an exception is thrown. After you insert inline assembly, the compiler is unaware of finer details (like any extra stack space the inline assembly allocated). Inline assembly (that is, mixing assembly and C/C++ code) makes it impossible for the compiler to accurately generate the pdata structures. For more information about pdata, see http://msdn.microsoft.com/en-us/library/1eyas8tf.aspx

For more information about assembly in 64-bit Windows, see:


The NO_STRICT type checking scheme is not supported in BCC64. If you have existing projects that use the NO_STRICT conditional define, you need to remove it.

For more information and instructions for removing NO_STRICT, see: C++ Applications Use STRICT Type Checking.

See Also