ISO/ IEC JTC1/SC22/WG14 N600


                           Document Number:  WG14 N600/X3J11 96-064
       
                               C9X Revision Proposal
                               =====================
       
       Title: Stack Overflow Checking
       Author: Konstantin V. Galichsky
       Author Affiliation: SC PHYSICON, Ltd.
       Postal Address: Moscow, Russia
       E-mail Address: [email protected]
       Telephone Number: 
       Fax Number: 
       Sponsor: 
       Date: September 9th, 1996
       Document History: none
       Proposal Category:
          __ Editorial change/non-normative contribution
          __ Correction
          XX New feature
          __ Addition to obsolescent feature list
          __ Addition to Future Directions
          __ Other (please specify)  ______________________________
       Area of Standard Affected:
          __ Environment
          XX Language
          __ Preprocessor
          XX Library
             __ Macro/typedef/tag name
             __ Function
             __ Header
          __ Other (please specify)  ______________________________
       Prior Art: _________________________________________________
       Target Audience: all
       Related Documents (if any): ________________________________
       Proposal Attached: XX Yes __ No, but what's your interest?

       It is not specified in ANSI C what is to be performed by
       every C/C++ environment after the stack overflow (SO). This
       makes some recursive algorithms unsafe in sence that the
       programmer has no way even to report the user about the
       reasons (invalid parameters and so on) of the SO occured.

       My proposal is following: the programmer may specify two
       things in a program:
       
       1) to define the function to be called on SO (SO-handler),
       
       2) to explicitly specify 'dangerous' places by call of
       special SO-checking standard library function.
       
       It is important to keep in mind that there are realizations
       of C which can check SO only by adding special code in the
       beginning of EVERY function.  This means the performance
       will be lost. So, the possibility to check SO 'everytime'
       must be optional, as in the existing realizations. That's
       why it is important to give the programmer the chance to
       explicitly call SO-checker in the beginning of dangerous
       (recursive, prone to SO) functions.
       
       Again, the realizations with system-level (hardware or
       software) SO-checking may implement the SO-checker as empty
       macro as they are tracing SO everytime.

       So, the environment must guarantee that by explicit or
       implicit SO detection in 'dangerous' functions the
       SO-handler will be called. And, optionally, it may detect
       SO always. 
       
       A program may use library SO-handler 'by default' (it may
       simply call abort()), or report the user about reasons of
       termination and terminate, or perform long jump and
       continue to work. In C++, SO-handler may throw special
       library exception.
       
       Possibly, an additional header file should be added into the
       standard library to declare the prototypes.
       
         // checkso.h
       
         typedef void (* so_handler) (void);
         so_handler set_so_handler (so_handler);
         void check_stack_overflow ();
       
         // checkso.cpp
       
         # include <checkso.h>
         # include <stdlib.h>
       
         static void standard_so_handler (void) {
             abort ();
         }
       
         static so_handler current_so_handler = standard_so_handler;
       
         so_handler set_stack_handler (so_handler soh) {
             so_handler prev_soh = current_so_handler;
             current_so_handler = soh ? soh : standard_so_handler;
             return soh ? prev_so_handler : standard_so_handler;
         }
       
         void check_stack_overflow () {
             // Realization-dependant implementation.
             // ...
         }
       
         // Example of user code.
       
         # include <stdio.h>
         # include <checkso.h>
       
         int fact (int n) {
             check_stack_overflow ();
             return n ? n*fact (n-1) : 0;
         }
       
         void my_sh () {
             printf ("To big value given\n");
             abort ();
         }
       
         void foo (void) {
             so_handler old_soh = set_so_handler (my_sh);
             fact (100000);
             set_so_handler (old_soh);
         }