Path: utzoo!utgpu!watmath!mks!tj From: tj@mks.UUCP (T. J. Thompson) Newsgroups: comp.lang.c Subject: Re: Run-time Checks for C Summary: common C practice disallows meaningful run-time pointer bounds checks Message-ID: <566@mks.UUCP> Date: 19 Nov 88 21:10:26 GMT References: <10113@umn-cs.CS.UMN.EDU> Organization: Mortice Kern Systems, Waterloo, Ont. Lines: 68 In article <10113@umn-cs.CS.UMN.EDU>, raghavan@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 */