Exceptions: Throwing Exceptions from Your Own Functions

OverviewHow Do IFAQ

It is possible to use the MFC exception-handling paradigm solely to catch exceptions thrown by functions in MFC or other libraries. In addition to catching exceptions thrown by library code, you can throw exceptions from your own code if you are writing functions that can encounter exceptional conditions.

When an exception is thrown, execution of the current function is stopped and jumps directly to the catch block of the innermost exception frame. The exception mechanism bypasses the normal exit path from a function. Therefore, you must be sure to delete those memory blocks that would be deleted in a normal exit.

To throw an exception

  • Use one of the MFC helper functions, such as AfxThrowMemoryException. These functions throw a preallocated exception object of the appropriate type.

    In the following example, a function tries to allocate two memory blocks and throws an exception if either allocation fails:

    {
        char* p1 = (char*)malloc( SIZE_FIRST );
        if( p1 == NULL )
            AfxThrowMemoryException();
        char* p2 = (char*)malloc( SIZE_SECOND );
        if( p2 == NULL )
        {
            free( p1 );
            AfxThrowMemoryException();
        }
       
        // ... Do something with allocated blocks ...
    
        // In normal exit, both blocks are deleted.
        free( p1 );
        free( p2 );
    }
    

    If the first allocation fails, you can simply throw the memory exception. If the first allocation is successful but the second one fails, you must free the first allocation block before throwing the exception. If both allocations succeed, you can proceed normally and free the blocks when exiting the function.

     – or – 

  • Use a user-defined exception to indicate a problem condition. You can throw an item of any type, even an entire class, as your exception.

    The following example attempts to play a sound through a wave device and throws an exception if there is a failure.

    #define WAVE_ERROR -5
    {
        // This Win32 API returns 0 if the sound cannot be played.
        // Throw an integer constant if it fails.
        if( !sndPlaySound("SIREN.WAV", SND_ASYNC) )
            throw WAVE_ERROR;
    }
    

Note   MFC’s default handling of exceptions applies only to pointers to CException objects (and objects of CException-derived classes). The example above bypasses MFC’s exception mechanism.