exception_handler

C compilerC++ compiler

exception_handler syntax

Read syntax diagramSkip visual syntax diagram#pragmaexception_handler (function_namelabel,0,com_area,class1,class2 ,ctl_action,msgid_list)

Description

Enables a user-defined ILE exception handler at the point in the code where the #pragma exception_handler is located.

Any exception handlers enabled by #pragma exception_handler that are not disabled using #pragma disable_handler are implicitly disabled at the end of the function in which they are enabled.

Parameters
function
Specifies the name of the function to be used as a user-defined ILE exception handler.
label
Specifies the name of the label to be used as a user-defined ILE exception handler. The label must be defined within the function where the #pragma exception_handler is enabled. When the handler gets control, the exception is implicitly handled and control resumes at the label defined by the handler in the invocation containing the #pragma exception_handler directive. The call stack is canceled from the newest call to, but not including, the call containing the #pragma exception_handler directive. The label can be placed anywhere in the statement part of the function definition, regardless of the position of the #pragma exception_handler.
com_area
Used for the communications area. If no com_area should be specified, zero is used as the second parameter of the directive. If a com_area is specified on the directive, it must be a variable of one of the following data types: integral, float, double, struct, union, array, enum, pointer, or packed decimal. The com_area should be declared with the volatile qualifier. It cannot be a member of a structure or a union.
class1, class2
Specifies the first four bytes and the last four bytes of the exception mask. The <except.h> header file describes the values that you can use for the class masks. It also contains macro definitions for these values. class1 and class2 must evaluate to integer constant expressions after any necessary macro expansions. You can monitor for the valid class2 values of:
  • _C2_MH_ESCAPE
  • _C2_MH_STATUS
  • _C2_MH_NOTIFY, and
  • _C2_MH_FUNCTION_CHECK.
ctl_action
Specifies an integer constant to indicate what action should take place for this exception handler. If handler is a function, the default value is _CTLA_INVOKE. If handler is a label, the default value is _CTLA_HANDLE. This parameter is optional.
The following are valid exception control actions that are defined in the <except.h> header file:
#define name Defined value and action
_CTLA_INVOKE Defined to 1. This control action will cause the function named on the directive to be invoked and will not handle the exception. If the exception is not explicitly handled, processing will continue. This is valid for functions only.
_CTLA_HANDLE Defined to 2. The exception is handled and messages are logged before calling the handler. The exception will no longer be active when the handler gets control. Exception processing ends when the exception handler returns. This is valid for functions and labels.
_CTLA_HANDLE_NO_MSG Defined to 3. The exception is handled but messages are not logged before calling the handler. The exception will no longer be active when the handler gets control. Exception messages are not logged. Msg_Ref_Key in the typedef _INTRPT_Hndlr_Parms_T is set to zero. Exception processing ends when the exception handler returns. This is valid for functions and labels.
_CTLA_IGNORE Defined to 131. The exception is handled and messages are logged. Control is not passed to the handler function named on the directive and exception will no longer be active. Execution resumes at the instruction immediately following the instruction that caused the exception. This is valid for functions only.
_CTLA_IGNORE_NO_MSG Defined to 132. The exception is handled and messages are not logged. Control is not passed to the handler function named on the directive and exception will no longer be active. Execution resumes at the instruction immediately following the instruction that caused the exception. This is valid for functions only.
msgid_list
Specifies an optional string literal that contains the list of message identifiers. The exception handler will take effect only when an exception occurs whose identifiers match one of the identifiers on the list of message identifiers. The list is a series of 7-character message identifiers where the first three characters are the message prefix and the last four are the message number. Each message identifier is separated by one or more spaces or commas. This parameter is optional, but if it is specified, ctl_action must also be specified.
For the exception handler to get control, the selection criteria for class1 and class2 must be satisfied. If the msgid_list is specified, the exception must also match at least one of the message identifiers in the list, based on the following criteria:
  • The message identifier matches the exception exactly.
  • A message identifier, whose two rightmost characters are 00, will match any exception identifier that has the same five leftmost characters. For example, a message identifier of CPF5100 will match any exceptions whose message identifier begins with CPF51.
  • A message identifier, whose four rightmost characters are 0000, will match any exception identifier that has the same prefix. For example, a message identifier of CPF0000 will match any exception whose message identifier has the prefix CPF (CPF0000 to CPF9999).
  • If msgid_list is specified, but the exception that is generated is not one specified in the list, the exception handler will not get control.

Notes on Usage

The handler function can take only 16-byte pointers as parameters.

The macro _C1_ALL, defined in the <except.h> header file, can be used as the equivalent of all the valid class1 exception masks. The macro _C2_ALL, defined in the <except.h> header file, can be used as the equivalent of all four of the valid class2 exception masks.

You can use the binary OR operator to monitor for different types of messages. For example,
#pragma exception_handler(myhandler, my_comarea, 0, _C2_MH_ESCAPE | \
                _C2_MH_STATUS | _C2_MH_NOTIFY, _CTLA_IGNORE, "MCH0000")
will set up an exception monitor for three of the four class2 exception classes that can be monitored.
The compiler issues an error message if any of the following occurs:
  • The directive occurs outside a C function body or inside a C statement.
  • The handler that is named is not a declared function or a defined label.
  • The com_area variable has not been declared or does not have a valid object type.
  • Either of the exception class masks is not a valid integral constant
  • The ctl_action is one of the disallowed values when the handler that is specified is a label (_CTLA_INVOKE, _CTLA_IGNORE, _CTLA_IGNORE_NO_MSG).
  • The msgid_list is specified, but the ctl_action is not.
  • A message in the msgid_list is not valid. Message prefixes that are not in uppercase are not considered valid.
  • The messages in the string are not separated by a blank or comma.
  • The string is not enclosed in “ ” or is longer than 4 KB.
  • The handler function specified is defined with argument optimization (#pragma argopt).
If a label is used as a user-defined exception handler, some of the code between the exception_handler pragma and the disable_handler pragma could be skipped if an exception occurs. Therefore, any declaration or statement in the exception range may be skipped causing variables to not be initialized or variable length arrays to not have storage allocated (since storage is allocated for variable length arrays at the time of their declaration). In the following example
  1. The assignment to z may cause an exception if i is zero. If so, control branches to LABEL.
  2. If an exception occurs, ptr will not set to &z and vla will not have its storage allocated.
  3. The use of *ptr and vla[0] may be illegal if ptr is not initialized and the storage for vla is not allocated.
void func(unsigned int i)
{
  unsigned int *ptr = NULL;
  unsigned int z; 
#pragma exception_handler(LABEL,0, _C1_ALL, _C2_ALL)
  z = 45/i;    // 1 
  ptr = &z;    // 2 
  unsigned int vla[z]; 
#pragma disable_handler 
LABEL: 
  vla[0] = *ptr;   // 3 
  return; 
}
In addition, because variable length arrays declare their storage at run time and that may cause a storage allocation exception, it is recommended to have an exception handler enabled for variable length array declarations.

See the ILE C/C++ Programmer's Guide for examples and more information about using the #pragma exception_handler directive.