martin@mwtech.UUCP (Martin Weitzel) (03/01/90)
In article <12246@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: >In article <MCDANIEL.90Feb27103334@amara.amara.uucp> mcdaniel@amara.uucp (Tim McDaniel) writes: >>Are standard library names utterly and completely reserved, or can I >>fake it with #define, as in >> #define malloc(bytes) my_malloc(bytes, __FILE__, __LINE__) > [correct parts of the answer deleted] > >It would be better to use some name other than malloc for this macro. Yes and No - it depends on why I (or the poster) want to do this. IMHO, there's a big 'philosophical' difference between languages like C, which obliges the programmer to do *all* error checking (namely for "fopen", "malloc" a.s.o., which may only fail under 'unusual conditions') and PASCAL, which does much more 'holding hands' at the cost, that the programmer has no chance to regain control, if a FILE cannot be opened, a NEW cannot make memory available a.s.o. This often has lead to the general assumption, that C is an 'unsafe' language, because programmers may tend to ommit error checking (because they have learned PASCAL earlier than C and think, it's not necessary, because they think "I'll add it later" and forget to do so, or because they consider the situation a "never happens" one). There is much moaning about this 'insecurity of C', heard from novices (and people, who happen to have an other favorite language than C), but it's very seldom noticed, that it takes NOT MORE THAN 1 (ONE) HEADER-FILE and a few additions to the library, to rectify most of it. (It may be valuable to do this, if you plan to teach courses on C.) The header file does exactly, what the poster proposes (and I'm glad ANSI did not make it illegal): You substitute 'unsafe' library functions, say "foo", by macros of the same name, which call similar named functions "my_foo" as the original poster proposed, or "sfoo" as I prefere, where the "s" stands for "safe". The "s"-functions are defined in a separatly compiled module, and call the respective original library function (and hence must *not* #include the header file, which redefines the name). Besides that, they do some error checking, print diagnostics (for which the hidden arguments __FILE__ and __LINE__ are fine) and may abort the program. This approach seems most useful for learning C, because the novice can concentrate to get the syntax and algorithms right, without cluttering up the progam with code for error checking. (IMHO, this is the reason, why PASCAL stepped along this road and is - in an unaugmented version - useless for 'real life' programming, were you often have to undo some earlier operations, if a later operation is not succesfull.) But you can make this scheme more sophisticated and usable for production programming. You only need to call the error handlers from the "s"-functions via function pointers, that can be altered from outside (but should default to diagnostic messages and/or termination). If you extend this idea further (eg keep the error handlers for each logical level of functions in separate tables and calling them via double pointers) you may even easily switch tables. The bottom line is, that you can have much of ADA's or PL/1's exception handling added to C. It requires no changes to the syntax of C, you must only make use of those features, which are allready there. -- Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83
karl@haddock.ima.isc.com (Karl Heuer) (03/03/90)
In article <681@mwtech.UUCP> martin@mwtech.UUCP (Martin Weitzel) writes: >In article <12246@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: >>It would be better to use some name other than malloc for this macro. > >Yes and No - it depends on why I (or the poster) want to do this. > >[C requires the user to do error checking; Pascal simply aborts on failure.] >This often has lead to the general assumption [that C is 'unsafe'], >but it's very seldom noticed, that it takes NOT MORE THAN 1 (ONE) >HEADER-FILE and a few additions to the library, to rectify most of it. I agree that it can be useful to have an error-handling version of malloc(), but I agree with Doug that it should be called by a different name. *Especially* if you're teaching a course! How are your students supposed to learn that there's a difference between standard malloc() and your local "improved" version? Side note: error handling is a botch in ANSI C; this was recognized by the Committee. There was no prior art that could be used to build a reasonable facility, and it was against the Charter to invent one from scratch, so they kept the system that Unix uses. As with other such situations, there's room for it to be fixed in the *next* standardization, if a good system is invented and tested in the meantime. With that in mind... >But you can make this scheme more sophisticated and usable for production >programming. You only need to call the error handlers from the "s"-functions >via function pointers, that can be altered from outside (but should default >to diagnostic messages and/or termination). Alternately, an implementation could provide these error-handling features in the actual library routines rather than in "s"-functions. The default action would have to be "ignore" (to retain compatibility with the current Standard), but there could be a simple way for the user to globally change this default. I don't much like using signal-like semantics, since it often means you have to use a messy longjmp() to recover. Another possibility is that when "safe mode" is enabled, routines continue to indicate errors quietly (i.e. by setting an internal flag which replaces errno), but only if no error is already pending. A routine iserror() would test and clear the internal flag. Thus, instead of if ((vp = malloc(siz)) == NULL) die(); one would write vp = malloc(siz); if (iserror()) die(); , and instead of (void)remove(tmpfile); /* okay if file already gone */ one would write remove(tmpfile); (void)iserror(); Unlike errno, there would be no risk that the error flag is "old". It would never be set by a successful routine, and one may not invoke any "unsafe" routine (i.e. a function that might set the flag) while it is set. Doing so would cause the program to abort with a signal. Any other ideas? Karl W. Z. Heuer (karl@ima.ima.isc.com or harvard!ima!karl), The Walking Lint
jv@mh.nl (Johan Vromans) (03/03/90)
In article <681@mwtech.UUCP> martin@mwtech.UUCP (Martin Weitzel) writes: > IMHO, there's a big 'philosophical' difference between languages like > C, which obliges the programmer to do *all* error checking (namely for > "fopen", "malloc" a.s.o., which may only fail under 'unusual conditions') > and PASCAL, which does much more 'holding hands' at the cost, that the > programmer has no chance to regain control, if a FILE cannot be opened, > a NEW cannot make memory available a.s.o. [ and much more ] A very elegant approach was taken in the early 70's in Burroughs Extended Algol. Some operations allowed multiple levels of control, e.g.: READ(INFILE,COUNT,BUFFER) -> if something goes wrong, the system would trap it READ(INFILE,COUNT,BUFFER)[EOF] -> EOF handled by program, others by system RESULT := READ(INFILE,COUNT,BUFFER) -> complete control by the program Real powerful language. They don't make them like that these days. Johan -- Johan Vromans jv@mh.nl via internet backbones Multihouse Automatisering bv uucp: ..!{uunet,hp4nl}!mh.nl!jv Doesburgweg 7, 2803 PL Gouda, The Netherlands phone/fax: +31 1820 62944/62500 ------------------------ "Arms are made for hugging" -------------------------