Delphi Exception Handling in C++

From RAD Studio
Jump to: navigation, search

Go Up to Exception Handling in C++Builder


C++Builder libraries may throw exceptions when something unexpected occurs. Since C++Builder libraries are written in Delphi, when you build C++ applications using C++Builder you need to understand how Delphi exception handling works, so that you can properly handle exceptions from libraries such as:

Catching Delphi Exceptions

Exceptions from Delphi libraries must be caught by reference:

try {
    // Code that uses Delphi libraries.
}
catch (ExceptionClass &E) {
    // Handling of Delphi exceptions of type ExceptionClass.
}

For example, to catch an exception of class Exception and show its Message on a dialog box:

catch (Exception &E) {
    ShowMessage(E.Message);
}

When catching exceptions from Delphi libraries:

  • You cannot use throw to reraise Delphi exceptions that were caught unless you are in the catching stack frame.
  • You are not responsible for freeing Delphi exception objects.
  • You must explicitly catch exceptions from Delphi libraries in C++Builder graphical applications.
    Note: If you do not explicitly catch these exceptions, the default exception handler of the GUI framework of your application catches them, and your application raises an External Exception EEFFACE.

Delphi Constructors May Throw Exceptions

C++ destructors are called for members and base classes that are fully constructed.
Delphi base class destructors are called even if the object or base class is not fully constructed.

Object Destruction, Exceptions Thrown from Constructors provides an example that shows what happens if an exception is thrown during object construction.

Throwing Delphi Exceptions

You must throw instances of Delphi exception classes from C++ by value:

throw ExceptionClass();

For example, to throw an exception of class Exception and define an error Message:

throw Exception("My error message");

Common Delphi Exception Classes in C++Builder

C++Builder includes a large set of built-in exception classes for automatically handling divide-by-zero errors, file I/O errors, invalid typecasts, and many other exception conditions. To catch these exceptions, your application must link to the RTL. If your application does not link to the RTL, to handle this type of issues you should use signal-handling APIs of each operating system that your application supports, such as Structured Exception Handling on Windows.

In addition, Language Support for the RAD Studio Libraries (C++) describes subtle language differences that can cause exceptions.

Common RTL Exception Classes

RTL exceptions include access violations, integer math errors, floating-point math errors, stack overflow, and Ctrl+C interrupts.

Exception class Description
EAbort Stops a sequence of events without displaying an error message dialog box.
EAccessViolation Checks for invalid memory access errors.
EBitsError Prevents invalid attempts to access a Boolean array.
EComponentError Signals an invalid attempt to register or rename a component.
EConvertError Indicates string or object conversion errors.
EDivByZero Catches integer divide-by-zero errors.
EExternalException Signifies an unrecognized exception code.
EInOutError Represents a file I/O error.
EIntOverflow Specifies integer calculations whose results are too large for the allocated register.
EInvalidArgument Can be raised by some functions in the System.Math unit for out of range parameters.
EInvalidCast Checks for illegal typecasting.
EInvalidOp Invalid floating-point operation. For example, Floating-Point Exception: Stack Fault.
EInvalidOperation Occurs when invalid operations are attempted on a component.
EInvalidPointer Results from invalid pointer operations.
EOleError Specifies OLE automation errors.
EOverflow Floating-Point Exception: Divide by 0, Domain or Overflow
EPropertyError Occurs on unsuccessful attempts to set the value of a property.
ERangeError Indicates an integer value that is too large for the declared type to which it is assigned.
ERegistryException Specifies registry errors.
System.SysUtils.EUnderflow Floating-Point Exception: Partial Loss of Precision or Underflow
EZeroDivide Catches floating-point divide-by-zero errors.

Common Data Access Exception Classes

Exception class Description
EDatabaseError Specifies a database access error.

Common VCL Exception Classes

VCL exceptions:

Exception class Description
EDBEditError Catches data incompatible with a specified mask.
EInvalidGraphic Indicates an attempt to work with an unrecognized graphic file format.
EMenuError Involves a problem with menu item.
EOleCtrlError Detects problems with linking to ActiveX controls.

Custom Exception Classes that Descend from Delphi Classes

You can declare a new exception class by making it a descendant of class Exception and creating as many constructors as you need (or copy the constructors from an existing class in Sysutils.hpp).

Portability considerations

Several runtime libraries (RTLs) are delivered with C++Builder. Most of them pertain to C++Builder applications, but one of them, cw32mt.lib, is the normal multi-threaded RTL that does not make any references to the VCL. This RTL is provided for support of legacy applications that may be part of a project but do not depend on the VCL. This RTL does not have support for catching operating system exceptions because those exception objects are derived from TObject and would require parts of the VCL to be linked into your application.

You can use the cp32mt.lib library, a multi-threaded runtime library, which provides memory management and exception handling with the VCL.

You can use two import libraries, cw32mti.lib and cp32mti.lib, for using the RTL DLL. Use cp32mti.lib for VCL exception support.

See Also