steve@endor.harvard.edu (Kaufer - Lopez - Pratap) (12/10/88)
I am just catching up on my net-mail, and have a comment on a subject discussed a few days ago: run-time checking in the C language. Warning: this is from a *>>> VERY BIASED SOURCE <<<* i.e. I work on a product, Saber-C, that does run-time checking for C programs. As mentioned before, the C language is a very difficult one in which to insert run-time checking. Just about every operation has some sort of checking that can be done. Arithmetic operations should check for over/underflow, pointer operations should check for bad pointer values, function calls should check the types and number of arguments, to name just a few. Several attemtps have been made to add some of these checks to various compilers, (i.e. the data general compiler mentioned earlier, bcc, safe-c), but to do all of this checking thoroughly is just too much of a burden for a compiler. By way of specifics, it isn't good enough to catch a pointer out-of-bounds by checking to see if it is outside of your data segment, the compiler should check to see if it is outside 'the object pointed to'. For many systems, this involved passing around the bounds of each object with the pointer. However, all of the existing libraries and unix system call interfaces REQUIRE that pointers be 4 bytes (well, at least for 32 bit computers). Users could either recompile the libraries (and the unix kernal) with this checkout compiler (sounds fun, right!?!), or interface routines can be developed that that convert between library code and the special run-time checked code, in which case the boundary info is lost, and there go half your pointer checks. Obviously, these checks should also work if the object pointed to is global, automatic or dynamically allocated. Has anyone here ever been bitten by a 'memory trashed' bug? Where the core dump is far removed from wherever the bug was found? A pointer problem, right? Well, bounds checking doesn't let that sort of thing happen... Another useful category for run-time checking is detecting memory inconsistencies: char *cp; int i, j; i = 10; cp = (char *)&i; *cp = 'a'; j = i; This last line uses the value of 'i', which has been 'damaged' by the legal (if dubious) dereference of 'cp'. It is tough to imagine a compiler putting in checks on *EVERY* reference to a memory location! A simpler example would be: double d; union U { int i; double d; } u; u.i = 2; d = u.d; Here we put an integer in the union, and then retrieve a double value. Probably something the programmer wants to be notified about.... Saber-C catches these problems by using a C interpreter. There is also a dynamic linker which allows interpreted code to be intermixed with object code, so that large projects can be debugged efficiently. I could obviously go on at length about all of the other benifits of Saber-C, but thats another story... - Steve Kaufer kaufer%saber@harvard.edu harvard!saber!kaufer Saber Software, Inc. (617) 876-7636