C++Builder 64-bit Windows Differences
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.
Contents
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:
- 64-bit Cross-Platform Application Development for Windows
- 64-bit Windows Data Types Compared to 32-bit Windows Data Types
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)
#else
#error Not a supported platform
#endif
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 namedfile
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 #include
s. 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:
- Using Precompiled Headers in 64-bit Windows C++ Applications
- Precompiled Headers Command Line Options for BCC64
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, obsoleteasm
,_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:
- http://clang.llvm.org/compatibility.html#inline-asm
- http://www.osdever.net/tutorials/view/a-brief-tutorial-on-gcc-inline-asm
- http://www.codeproject.com/Articles/15971/Using-Inline-Assembly-in-C-C
- http://wiki.osdev.org/Inline_Assembly/Examples
NO_STRICT Macro
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
- BCC64.EXE, the C++ 64-bit Windows Compiler
- ILINK64.EXE, the 64-bit Incremental Linker
- TLIB64.EXE, the Library Manager for 64-bit Windows
- 64-bit Windows "Hello World" Cross-Platform Application (Delphi and C++)
- Stricter C++ Compiler (BCC64)
- Upgrading Existing C++ Projects to 64-bit Windows
- Debugging C++Builder 64-Bit Windows Applications
- C++11 Features (BCC64)
- Using Precompiled Headers in 64-bit Windows C++ Applications
- Release Notes for C++Builder 64-Bit Windows
- What's New in C++Builder 64-Bit Windows
- 64-bit Windows Data Types Compared to 32-bit Windows Data Types