Intel® Fortran Compiler 17.0 Developer Guide and Reference
There are two aspects to creating custom handlers for Fortran DLL applications:
Containing errors and exceptions
Enabling floating-point traps
If you are building a Fortran DLL and intend to call it from a main program written in some other language, you want to be careful that errors and exceptions in the DLL do not crash your main application.
Here are a few basic principles to keep in mind if you are building a Fortran DLL:
Construct your library routines so that they return a status to the caller and let the caller decide what to do.
To return an expected status to the caller, you need to be defensive in your library code, so consider these other principles:
Where it makes sense, have the library code check input arguments passed in from the caller to make sure they are valid for whatever the library routine is going to do with them. For example, suppose the routine implements some numerical algorithm that has a valid domain of inputs it can act on and still produce well defined behavior. You can check the input arguments before you execute the algorithm and avoid unexpected behavior that might otherwise result (like unexpected floating-point exceptions). You might use Fortran intrinsic procedures like ISNAN and FP_CLASS to detect exceptional IEEE numbers. Your DLL code needs to return a status to the caller indicating the problem and let the caller take the appropriate action (gracefully shut down the application, try again with different input, etc.).
In your library code, always check the success or failure of calls to I/O routines and dynamic memory allocation/deallocation. In Fortran, the I/O statements have optional ERR, END, EOR, and IOSTAT arguments that you can use to determine if the I/O requested was successful. Dynamic memory ALLOCATE and DEALLOCATE statements have an optional STAT specifier that allows you to obtain the status of the dynamic memory allocation/deallocation and prevent program termination.
If you do not specify an action to take on an error, the Fortran run-time system has no choice but to deal with the error as an unhandled severe error and terminate the program. For a specific example of using IOSTAT and ERR to deal gracefully with an OPEN statement that gets a file-not-found error, see Using the IOSTAT Specifier and Fortran Exit Codes. You can do the same sort of thing in your code, but just return the status back to your Visual Basic* or other non-Fortran main program and let it decide what to do.
Try to write your DLL code so unexpected program exceptions cannot occur, but devise a strategy for dealing with unexpected exceptions if they do happen. The most effective alternative for dealing with an exception is to use Windows Structured Exception Handling support to gain control when an exception happens. Wrap all your DLL routine calls in C try/except constructs and have the except() filter expression call a routine you define which determines how to respond.
Before you can worry about how you will handle a floating-point trap condition occurring in a DLL, you have to consider the problem of unmasking those traps so they can occur. If you are compiling with fpe[:]3 and polling the floating-point status word to check for exceptions, you do not have to worry about the problem of unmasking traps. You do not want traps unmasked in that case.
If your strategy is to compile with fpe[:]0 and allow traps on floating-point exceptions, you need to take action to unmask the traps in the floating-point control word because most other languages mask traps by default.
Recall that a Fortran Console or Fortran QuickWin (or Standard Graphics) application would have unmasked traps for you automatically because the Fortran run-time system provides the main program and calls your MAIN__ which executes some prolog code before the actual application code starts. You do not have that in a Fortran DLL called by some other language. Different languages establish different initial environments. You must provide the desired initial environment yourself.