Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site cyb-eng.UUCP Path: utzoo!linus!philabs!cmcl2!seismo!ut-sally!cyb-eng!howard From: howard@cyb-eng.UUCP (Howard Johnson) Newsgroups: net.lang.c Subject: Re: makenode() gotcha Message-ID: <785@cyb-eng.UUCP> Date: Thu, 14-Nov-85 18:26:37 EST Article-I.D.: cyb-eng.785 Posted: Thu Nov 14 18:26:37 1985 Date-Received: Sat, 16-Nov-85 07:29:27 EST References: <2482@brl-tgr.ARPA> <118@bsdpkh.UUCP> Distribution: net Organization: Cyb Systems, Austin, TX Lines: 50 A fix to the following 'test' program still has a slight bug. As a matter of design, adding a simple function removes all kinds of nasty portability issues (i.e., sizes of pointers, paramter passing, etc.). >> struct node { int op; struct node *left, *right; double val; } >> *lp, *rp, *p, *makenode(); >> double value; /* constant value from lex */ >> ... >> p = makenode( 'x', lp, rp ); /* create multiply node */ >> ... >> p = makenode( 'k', value ); /* create real constant node */ >> ... >> struct node *makenode( op, arga, argb ) >> int op; struct node *arga, *argb; >> { extern char *malloc(); >> ... >> case 'k': /* real constant */ >> new->val = *(double *)&arga; /* XXX */ >> break; >> } >> return new; >> } >> >> The code failed at point "XXX". The exercise for the >> student is to figure out precisely WHY it fails ...... The attempted fix needs its indirection: > p = makenode ('k', &value ); ... new->val = *((double *)arga); /* you forgot the indirection */ Better! struct node * makeconst(value) double value; { register struct node *new; if ((new = (struct node *) malloc(sizeof *new)) != NULL) { new->op = 'k'; new->val = value; } return(new); } -- ..!{seismo,topaz,mordor,harvard,gatech,nbires,ihnp4}!ut-sally!cyb-eng!howard (ordered best to worst); also ..!ut-ngp!cyb-eng!howard +1 512 458 6609