The 25 days of C++mas - December 5 - stricter C++Builder Win64 compiler

By: David Intersimone

Abstract: David I gives tips for working with the new C++Builder 64-bit Windows compiler

This is a copy of a blog post from David I's Sip from the Firehose blog. Click to blog post title below to see the original blog post and comments.

  The 25 days of C++mas - December 5 - stricter C++Builder Win64 compiler

In providing support for the C++11 standard, the C++Builder 64-bit compiler for Windows is more strict than the C++Builder 32-bit compiler. As a developer you have the choice for which compiler you want to use depending on your platform needs.  If you want to build C++ applications for Windows and Mac OSX, use the 32-bit C++Builder compiler.  If you want build Windows only applications, you can use either compiler depending on our application needs.  VCL and FireMonkey component libraries are provided for both the 32-bit and 64-bit C++ compiler.  This blog post will detail some of the differences between the two compilers - BCC32 and BCC64.

Structural Syntax

  • BCC32 allows one to mix __try and catch.
  • BCC64 wants try/catch (standard C++) or __try/__except/__finally (Microsoft extensions).

Type Conversions

Assigning literal C-strings to char * generates a warning unless that pointer is declared const.
BCC32 allows assignment between char * and unsigned char* without any warning; in BCC64 this is a simple type mismatch error.

Implicit conversion from int to (classic, not type-safe) enum is allowed in BCC32 with a warning. In BCC64, implicit conversion is not allowed, and requires a cast. A common case is with enums like TColor and TCursor:

    TColor stones = (TColor) 0;  // instead of defaulting to random color, paint it black
    // Note: Vcl.Graphics.hpp does define the TColor clBlack

Defining Static Members

C++ static data members must be defined in only one place in your application. You should declare them in your class declaration in a header, and then define the data member in a source file (not in a header file).

For example:

    struct X { static int static_member; };
    #include "foo.h"
    int X::me;
    #include "foo.h"
    int some_function() { return X::me; }

In this example, foo.cpp has the definition of X::me, and bar.cpp shows a use. The static member is declared in foo.h, but only defined in foo.cpp.

BCC32 allows multiple definitions of X::me, in violation of the C++11 standard, so you could do the following:

    struct X { static int static_member; };
    int X::me;

In the case above (erroneous for BCC64, but allowed by BCC32), you are defining the static data member in the header, which will result in multiple definitions of X::me, one for each location the header is included. Our 64-bit tools do not permit this, and you might see linker errors such as this:

    [ilink64 Error] Error: Public symbol 'triplet::sum' defined in both module C:\USERS\WIN764\NODES.O and C:\USERS\WIN764\UNIT1.O

If you get these duplicate symbol definition errors from the linker for static data members, you should look for the erroneous pattern above, and fix your code to meet the ‘one definition’ requirement for static data members.

Differences between C++64 and C++32

  • BCC64 is also a preprocessor, when run with the -E switch. There is also a separate CPP64.EXE preprocessor.
  • BCC64 enforces template two-phase lookup. That is, names that are not tied to a dependent type are looked-up in the first phase (before instantiation) and might lead to errors that BCC32 did not report.
  • BCC64 allows a default argument only in a function declaration. BCC32 allowed default arguments in a function pointer or closure declaration as well.
  • BCC64 does not allow the use of sizeof in a preprocessor directive, such as #if sizeof(ATypeName) > 20.
  • BCC64 is stricter about conversions. For example, converting string constants to char* generates a warning (conversion from string literal to char * is deprecated). On the other hand, initializing a char* with an unsigned char* results in a plain error (Cannot initialize a variable of type ‘char *’ with an rvalue of type BYTE *, also known as unsigned char *).
  • BCC64 does not allow you to mix __try with catch: this is because catch must be used with try; and __try must be used with __except and/or __finally.
  • Unicode identifiers are not supported by BCC64.
  • CPP32 supports the -Hp option and prints header guard information that is used by the PCH Wizard.
  • CPP32’s default is not Unix style #line, and so forth.
  • The final (C++), deprecated and noreturn C++0x attributes are not supported by the 64-bit Windows C++ compiler. See Workaround for C++0x attributes for a workaround in BCC64.
  • Many BCC32 options are not supported by BCC64, and vice versa; see Options Not Supported by BCC64

If you want to make sure your C++ code works on Windows and Mac OSX, then create your project and start with the 32-bit target platforms for Windows and OSX. You can also then add the 64-bit Windows platform target and rebuild to see if there is any C++ code that will need #ifdefs to work with both compilers. Note: _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.

Watch/Download the C++Builder 64-bit Compiler Preview

I cover additional details about the 64-bit C++Builder compiler in the preview video.  Watch the C++ 64-bit compiler preview video on YouTube at You can also download the MP4 video file at  The preview video is 9 minutes long.

CodeRage 7 C++ Conference, December 10-12, 2012

The CodeRage 7 C++ conference starts next Monday, December 10, 2012 at 6am Pacific Standard Time (14:00 UTC).  There are 3 days of C++ sessions including my special live, online conversation with Bjarne Stroustrup at 8am PST (16:00 UTC) on Monday.  Some of the C++ sessions you won’t want to miss are included in my blog post on November 21 -

Happy C++mas!

During the first 25 days of December leading up to Christmas, I will blog about the upcoming release of the C++Builder 64-bit compiler for Microsoft Windows and C++Builder XE3support for building VCL and FireMonkey 2 applications.

Server Response from: ETNASC04