|
CX Framework
Cross-platform C utility framework
|
Data Structures | |
| struct | ExceptionInfo |
Macros | |
| #define | ptThrow(code, msg) _ptry_throw(code, msg) |
| #define | ptRethrow _ptry_throw(_ptry_exc.code, _ptry_exc.msg) |
| #define | ptTry |
| #define | ptFinally |
| #define | ptCatch |
| #define | ptCode _ptry_exc.code |
| #define | ptMsg _ptry_exc.msg |
Typedefs | |
| typedef struct ExceptionInfo | ExceptionInfo |
| typedef int(* | ptUnhandledHandler) (ExceptionInfo *einfo) |
Functions | |
| void | ptRegisterUnhandled (ptUnhandledHandler handler) |
| void | ptUnregisterUnhandled (ptUnhandledHandler handler) |
Advanced Feature: Exception handling with try/catch/finally semantics.
Provides exception handling built on protected blocks, allowing errors to propagate up the call stack with automatic cleanup. However, this system has important semantic differences from exception handling in languages like C++ or Java.
Performance Warning:
Exception handling inherits all the performance costs of protected blocks:
Critical Semantic Differences:
ptCode to determine if an exception actually happenedptCode == 0 means no exceptionptCode and use ptRethrow for selective handlingWhen to Use:
When NOT to Use:
Example:
| #define ptCatch |
ptCatch { }
Exception handler block that ALWAYS executes and stops exception propagation.
The ptCatch block MUST immediately follow a ptTry block. It is similar to ptFinally but with a critical difference: ptCatch stops exception propagation by default.
Critical Semantic Differences from C++/Java:
ptCode to determine if an exception happenedptCode == 0 means normal execution (no exception)ptCode != 0 means an exception occurredptCode to filter exception typesptRethrow to propagate exceptions you don't handleptRethrowExample:
| #define ptCode _ptry_exc.code |
ptCode
The exception code of the currently active exception, or 0 if there is none.
Use inside ptCatch or ptFinally blocks to check if an exception occurred and to determine the exception type.
Example:
| #define ptFinally |
ptFinally { }
Cleanup block that executes after a ptTry, whether an exception occurred or not.
The ptFinally block MUST immediately follow a ptTry block. It executes after the ptTry completes or an exception occurs. If an exception occurred, it is automatically re-thrown after the ptFinally block completes, propagating to the caller's handler.
Use ptFinally when:
Example:
| #define ptMsg _ptry_exc.msg |
ptMsg
The exception message of the currently active exception, or NULL if there is none.
Points to the static string literal passed to ptThrow(). Use inside ptCatch or ptFinally blocks to access the error message.
Example:
| #define ptRethrow _ptry_throw(_ptry_exc.code, _ptry_exc.msg) |
ptRethrow
Re-throws the currently active exception to a handler further up the call stack.
Used inside a ptCatch block to propagate an exception after performing local cleanup or logging. This is the mechanism for selective exception handling - catch specific exception codes locally and rethrow others.
Example:
| #define ptThrow | ( | code, | |
| msg | |||
| ) | _ptry_throw(code, msg) |
Throws an exception to be caught by a ptCatch or ptFinally block up the call stack.
An exception consists of a numeric code (application-defined) and a message. Control transfers immediately to the nearest ptCatch/ptFinally block, unwinding the stack and executing any cleanup code along the way.
| code | Application-specific numeric exception code (integer constant) |
| msg | Exception message - MUST be a static string literal |
Critical Requirements:
ptThrow(ERR_IO, "File not found")ptThrow(ERR_IO, buffer) is WRONGptThrow(ERR_IO, strdup(msg)) is WRONGExample:
| #define ptTry |
ptTry { }
Begins a try block for exception handling.
If an exception occurs inside the ptTry block, execution transfers to the immediately following ptCatch or ptFinally block. One or the other is REQUIRED - a ptTry without a matching ptCatch or ptFinally is a compile error.
Key Differences from C++/Java:
return is not allowed within the try blockIf an exception is not caught anywhere in the call stack, the unhandled exception handler is invoked (default: terminates the program with an error).
Example:
| typedef struct ExceptionInfo ExceptionInfo |
Exception information structure.
Contains details about an exception that is being thrown or is currently active. This is stored in thread-local storage during exception processing.
| typedef int(* ptUnhandledHandler) (ExceptionInfo *einfo) |
| void ptRegisterUnhandled | ( | ptUnhandledHandler | handler | ) |
Registers a handler for uncaught exceptions.
The handler is called when an exception is thrown with no matching ptCatch block up the call stack. This is a last-resort mechanism for error reporting or recovery.
| handler | Callback function that receives the exception information. Return 0 to abort the program, or 1 to resume execution. |
If multiple handlers are registered, they must ALL return 1 for execution to resume. Execution resumes after the outermost ptFinally block, or immediately after the throw if no ptTry blocks exist.
Example:
| void ptUnregisterUnhandled | ( | ptUnhandledHandler | handler | ) |
Unregisters a previously registered handler for uncaught exceptions.
| handler | The handler function to remove |