Path: utzoo!mnetor!uunet!husc6!mailrus!tut.cis.ohio-state.edu!bloom-beacon!gatech!mcnc!decvax!cca!g-rh From: g-rh@cca.CCA.COM (Richard Harter) Newsgroups: comp.lang.c Subject: Re: The D Programming Language Message-ID: <25387@cca.CCA.COM> Date: 8 Mar 88 08:40:37 GMT References: <25284@cca.CCA.COM> <1354@laidbak.UUCP> Reply-To: g-rh@CCA.CCA.COM.UUCP (Richard Harter) Organization: Computer Corp. of America, Cambridge, MA Lines: 87 In article <1354@laidbak.UUCP> daveb@laidbak.UUCP (Dave Burton) writes: >In article <25284@cca.CCA.COM> g-rh@CCA.CCA.COM.UUCP (Richard Harter) writes: >>Here is another feature for D whose absence in C has been irksome to >>me -- I would like to be able to return several items from a function. >>... But how do I get stuff back. >>... Things which are returned need a mechanism equivalent to pass >>by address. >Please don't design D until you understand C. Er, Dave, may I suggest it is inadvisable to make remarks such as "Please don't design D until you understand C". I am not a C guru; I read with respect the comments of people such as Chris Torek and Henry Spencer. I don't need to be a complete expert in the language. None-the-less I have been programming for 27 years, writing C for six of those years, have written ~100,000 lines of C, and have dealt with the vagaries of C implementations on a variety of operating systems. >C has had pass by reference for a very long time (since its inception?). Actually C has never had pass by reference -- what it has had is a facility for simulating call by reference, which is a somewhat different matter. >The following useless code illustrates: > > int flag, foobar(); > x = foobar(&flag); > ... > int foobar(arg) > int *arg; > { > *arg = 1; > return 0; > } > >Now, what could be simpler? And this is what I was alluding to when I referred to playing games with pointers. In the call statement you have to add an &; in each reference in the routine you add a *. You have to also select one item as a distinguished item which is returned by the function among those that are returned. Of course you can do this -- you don't have much option about it. But it is a kludge, and it is prone to error. Throughout the code you "mean" flag, but sometimes you write &flag, and sometimes you write *flag, depending on where you are. Fortunately, the effects of ommitting an & or a * are so drastic that typographic bugs of this sort are caught immediately. But I've seen it come up a number of times. A more subtle point is that there is a difference in semantics between returning a list and passing things through the calling sequence. A returned value is private unless it is explictly declared as a global; an item passed through a calling sequence may be a global and the called routine does not know this. For example, FILE 1: int x; foo () { .... x = 2; baz(x,&x); } FILE 2: extern x; baz(in,out) int in, *out; { *out = 1; ... *out = *out + x; } is quite different from the same code where baz is a function returning a value which is declared internally. Call by reference is subject to unintended aliasing, whether it be real call by reference or simulated call by reference. Finally, there is one other annoying consequence of the pointer hack. You can run into pointer to 0 dereferencing problems if you aren't careful. You shouldn't, but you can. -- In the fields of Hell where the grass grows high Are the graves of dreams allowed to die. Richard Harter, SMDS Inc.