#include Paths and Lookup

For example, Clang-enhanced C++ compilers do 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 Clang-enhanced C++ compilers and BCC32:

Precompiled Headers

Compared to BCC32, precompiled headers work a little differently for Clang-enhanced C++ compilers. Each C++ project can have only one precompiled header, and a default precompiled header (named projectPCHn.h) is generated for each new C++ project.

Object and Library File Format

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

__property: Compound and Chained Assignment

Clang-enhanced C++ compilers support compound assignment of __property, while BCC32 does not.

The objects of the keyword __property are not like fields or members. They should be used in simple assignments.

Although both BCC32 and the Appmethod Clang-enhanced C++ compilers allow __property to be used in compound assignments such as:

Form1->Caption+=DateToStr(Now());

BCC32 only invokes the getter, not the setter. Therefore we recommend that you avoid such constructs when targeting multiple platforms.

None of these compilers support the usage of __property in chained assignment, as in:

Button2->Caption=Button1->Caption=DateToStr(Now());// Error

Deprecated BCC32 Extensions and Keywords

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

Inline Assembly

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.

Clang-enhanced C++ compilers support inline assembly in a different style than the inline assembly supported by BCC32:

Different Assembly syntax:

The Assembly syntax supported by Clang-enhanced C++ compilers is line-by-line AT&T syntax, not the more familiar block-of-Intel syntax.

Potential exception handling and debugging problems:

The exception handling of the compiler 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 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. Lack of support for inline assembly is fairly common; for exceptions (and debugging) to work, 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

Try Blocks Cannot Handle Some Exceptions

Synchronous exceptions are exceptions raised using a throw statement in your program or in the libraries that your program uses. Compilers know where and when these exceptions raise.
Asynchronous exceptions are exceptions that come from the operating system and may raise at any time, such as divisions by zero or access violations.

Standard C and C++ are designed to handle synchronous exceptions only. However, when your Appmethod C++ applications link to the RTL, you are adding your applications the ability to catch asynchronous exceptions as well.

However, Clang is designed for synchronous exceptions only, and it does not support non-call exception handling. If a try block contains no throw statements and no calls to functions that may contain throw statements, Clang ignores any catch and finally blocks associated with that try block. That is, if a try block cannot throw any synchronous exception, you cannot catch any asynchronous exception in that try block either.

For example:

floata=1;floatb=0;try{try{a=a/b;// The RTL throws an asynchronous exception (division by zero).}__finally{// Execution never reaches this point.}}catch(...){// Execution never reaches this point.}

Instead of catching these special exceptions that Clang-enhanced compilers cannot handle, you should do either of the following:

Move the code that may raise an asynchronous exception to its own function and call that function from your try block.

Try to prevent these exceptions from ever raising. For example, you could check the value of b before you perform the division.

Note: If you do not handle asynchronous exceptions, the default exception handler of the GUI framework of your application catches them, and your application raises an External Exception EEFFACE.