[comp.os.msdos.programmer] C error handling

rdt155r@monu6.cc.monash.edu.au (mr r vanschyndel) (09/21/90)

Hi there!

I just read the discussions in this group and thought I'd add my two cents
worth.  It relates to the C compiler's response to various types of errors
and an error handling mechanism at runtime.

One of the most common errors made (by me especially), is to have one too many
open braces in some function definition, resulting in spurious error messages
through the rest of the module.  This is especially frustrating to novice C
programmers, confused by the compilers erratic behaviour.  I'm sure tthere are
many more tales of horror along this line.

Problems like this occur because of the context-sensitivity of parts of the
language.  The compiler can get completely out of synch in certain cases,
resulting in cryptic, uncomprehensible and irrelevant error messages.

While some of this behaviour is undoubtedly implementation-dependent (Turbo-C's
error messages are much more useful than Microsoft's), some is a result of the
language definition (such as the brace business above).

A simple solution might be to add two optional reserved words to the 
language -- 'function' and 'procedure' (synonymous with a void function).

Since C does not allow nested functions, they would act as resynchronising 
operators -- the compiler should only accept them while it is parsing in
between functions.  If encountered at any other time, they would signify an 
error, but the compiler could reset its 'brace-counter' and hence resynchro-
nise.

Since the presence of these keywords is purely optional, they can be #defined
to nothing when ported.

Any comments, suggestions ?


-------------------------------

Another pet hate of mine are the C facilities for error handling, although
this may only be due to my ignorance of all the different methods in use.

The standard approach of many library functions such as malloc() and fopen()
is to return NULL or some other special value on failure.  The biggest problem
with this is the way your program logic can get totally obscured with error
tests.

Another approach is to use printf's to stderr -- obviously unsatifactory in
many applications using wimdows (such as X, NeWS, curses, etc.).  Even
setting up an error window seems a kludge unless the windowing environent 
itself can be made to use it.

A third approach might be to set up nested setjmp/longjmp frames, so that even 
library routines will longjmp rather than return error statuses (statii ??).
This seems to suffer a lack of an ability to diagnose the error from within
the error routines unless the important variables are global.  How would you
'RESUME' or 'RETRY' the operation that caused the error?

The last approach I can think of is similar top the use of 'matherr' to catch
Division by zero and sqr(-1) type errors.  This approach would seem to answer
the question above -- but only if the language implements dynamic varaible
scoping (which it doesn't, of course).

I realize that my comments and questions are rather vague, but is there a 
generalized approach to error handling that could incorporated into the 
language, that could ease construction of user friendly (read: idiot-proof)
software ?

Ron

-- 
Ron van Schyndel                      rdt155r@monu6.cc.monash.oz   (...oz.au)
The Department of Physics,            rdt155r%monu6.cc.monash.oz@uunet.UU.NET
Monash University (Caulfield Campus)  {hplabs,mcvax,uunet,ukc}!munnari!monu6..
PO Box 197, CAULFIELD EAST,           Phone:+613-573-2567   Fax:+613-573-2748 

marcb@hp-ptp.HP.COM (Marc Brandis) (09/28/90)

>I just read the discussions in this group and thought I'd add my two cents
>worth.  It relates to the C compiler's response to various types of errors
>and an error handling mechanism at runtime.

>One of the most common errors made (by me especially), is to have one too many
>open braces in some function definition, resulting in spurious error messages
>through the rest of the module.  This is especially frustrating to novice C
>programmers, confused by the compilers erratic behaviour.  I'm sure tthere are
>many more tales of horror along this line.

>Problems like this occur because of the context-sensitivity of parts of the
>language.  The compiler can get completely out of synch in certain cases,
>resulting in cryptic, uncomprehensible and irrelevant error messages.

>While some of this behaviour is undoubtedly implementation-dependent (Turbo-C's
>error messages are much more useful than Microsoft's), some is a result of the
>language definition (such as the brace business above).

>A simple solution might be to add two optional reserved words to the 
>language -- 'function' and 'procedure' (synonymous with a void function).
You seem to have stepped in one of the many holes new C programmers step
into. However, the reason for these problems is not only the fact that
there are some context-sensitive parts in the C definition, but that 
there is no "real grammar" at all. You cannot parse C with either one
of the two standard parsing methods: recursive descent which parses
LL(1) grammars or LR(1)-parsers. You have to use LR(1)-tools like
yacc and kludge them to resolve some parsing conflicts to the definition
of C and to handle lots of cases in the right way (creating context).
Part of the problem are the very complicated precedence rules in C.

But the problem will not be solved by adding synchronization points,
as the real problem is not the error messages created by the compiler.
Assume that you not only forget a closing brace, but that you also
delete by error an opening brace, as in the following example.

for (........) {
    stat1;
    if (......) {
	while (.....) {
	      stat2;
	      stat3;
        }
}

Here, the closing brace of the if-statement is missing. Now assume
that the opening brace of the for-statement gets lost by some
editing. Then this code sequence is perfectly acceptable for the
compiler, but it does not do what you expect. Actually, I remember
somebody telling me that he his found such an error in a very popular
benchmark, causing it to execute only part of a loop and screwing up
the results significantly.

I do not think that these problems can be solved by adding some
features to C (maybe by removing some). If you want to avoid these
problems, avoid C and use languages like Modula-2 or Ada.


mine has found