Skip to content

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 XE3 support for building VCL and FireMonkey 2 applications.

{ 3 } Comments

  1. Simon Hooper | December 7, 2012 at 3:20 am | Permalink

    Hi David

    Basically since using C++Builder 2007, our developers have been unable to debug our C++ applications in a stable fashion, e.g. unable to view certain local variables. 2009, 2010, XE, XE2 and XE3 have had big problems. We were forced to move away from 2007 for a number of reasons, one being the daily crash of the IDE editor. The situation is getting serious and we have not been helped by support even though we have paid support and maintenance every year since it started. The only time I have managed to get bug fixes is through beta testing. Does the move to a 64-bit compiler change this situation? Will the fact that the new compiler is a total rewrite mean that these type of debugging problems will become a thing of the past? All we want to do is inspect and watch our variables, not a big thing to ask. One of our developers had to restart 30 times one day last week due to IDE crashes.

    Sorry for rant but I have held back for too long now.


  2. David Intersimone | December 11, 2012 at 5:59 am | Permalink

    Simon - I have forwarded your comment to Product Management and R&D. Someone should be contacting you directly. Have you posted any Quality Central (QC) problem reports? If yes, can you let me know the QC #’s so that I can forward them to the team.

    I know that the debugger has been continuously improved over the years. There is a different debugger for the 64-bit compiler but it does use the IDE for the UI portion. Not sure if this will change any specific things your team members are running into. But working together, we can track them down.


  3. Simon Hooper | December 11, 2012 at 11:57 am | Permalink

    Thanks David. We go through support rather than QC. The last 2 debugging support cases (which have had no response yet) have reference 00295463 and 00295460.

Post a Comment

Your email is never published nor shared. Required fields are marked *

Bad Behavior has blocked 4 access attempts in the last 7 days.