Run-time Checks for C

T. J. Thompson tj at mks.UUCP
Sun Nov 20 07:10:26 AEST 1988


In article <10113 at umn-cs.CS.UMN.EDU>, raghavan at umn-cs.CS.UMN.EDU (Vijay Raghavan) writes:
> 
>    I made a casual statement in a local bulletin board to the effect that
> the C language definition doesn't really preclude any implementation from
> doing certain run-time checks (for array bounds, type checking, referring
> contents of uninitialized pointer variables &c), it's just that most
> (okay, all!) implementations don't do any such checking because of efficiency
> reasons. Now I'm not sure that this statement is really true (I mean I'm not
> sure that sufficient information can always be passed to the compiler for it
> to generate code for meaningful run-time checks.) 
>
Consider the following semi-realistic code fragment:

typedef struct {
	int type;
	union {
		int ival;
		double dval;
		struct {
			int hval;
			char name[1];
		} n;
	} v;
} nodeT;

nodeT*
namenode(char* name)
{
	nodeT* np;

	if ((np=(nodeT*)malloc(sizeof(nodeT)+strlen(name))) != NULL) {
		np->type = NAME;
		np->v.n.hval = hash(name);
		(void)strcpy(np->v.n.name, name); /* run-time check here? */
	}
	return (np);
}

I suggest that no amount of cleverness on the part of the compiler and malloc
can limit a pointer derived from np->v.n.name to the precisely correct range
(np->v.n.name[0] .. np->v.n.name[strlen(name)]).

The compiler could limit any pointer derived from np->v.n.name to that value
only, based on the length of the array in the type declaration. This would
cause the strcpy to fail (and would probably break 98% of existing programs).

The pointer derived from np->v.n.name could be limited to the object returned
by malloc (i.e. the limits on np->v.n.name could be inherited from np).
This would permit np->v.n.name[-1]=0; clearly wrong.

There could be a special arrangement to allow the relaxation of limits on
a trailing array member of an aggregate; but consider:

union {
	double d[2];
	int i[2];
} coord;

Then could write coord.i[2]=0; clearly wrong.

I doubt many people would accept the cost of run-time checking if it were
not able to catch the vast majority of errant pointers as soon as possible
(after all, we already get `segmentation violation -- core dumped').
-- 
     ll  // // ,'/~~\'   T. J. Thompson              uunet!watmath!mks!tj
    /ll/// //l' `\\\     Mortice Kern Systems Inc.         (519) 884-2251
   / l //_// ll\___/     35 King St. N., Waterloo, Ont., Can. N2J 2W9
O_/                                long time(); /* know C */



More information about the Comp.lang.c mailing list