Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!mailrus!ames!pasteur!ucbvax!amdcad!rpw3 From: rpw3@amdcad.AMD.COM (Rob Warnock) Newsgroups: comp.lang.c Subject: Re: Unnecessary Macros Message-ID: <23138@amdcad.AMD.COM> Date: 5 Oct 88 12:11:25 GMT References: <70279@sun.uucp> <225800075@uxe.cso.uiuc.edu> <7213@bloom-beacon.MIT.EDU> <8814@ihlpb.ATT.COM> Reply-To: rpw3@amdcad.UUCP (Rob Warnock) Organization: [Consultant] San Mateo, CA Lines: 31 The first "implementation language" I ever used (*not* counting FORTRAN!) was BLISS-10 (circa 1971 on a PDP-10). BLISS is an "expression language", meaning that almost every construct has a value. If you have trouble with this, imagine if the ";" had the same semantics as C's "," operator. So the value of a "block" (a BEGIN-END pair, like C's {} pairs) was the value of the last expression (C's "statement") in it. Since blocks can have declarations of local variables, this macro problem we've seen so much comment on was trivial (shown using C-like syntax, not real BLISS): #define square(x) (int sqr_tmp, sqr_tmp = (x), sqr_tmp * sqr_tmp ) ... foo = square(x++); /* x**2, with only one increment of x */ foo = square(square(x++)); /* x**4, with only one increment of x */ The "sqr_tmp" is local to the body of the macro, and, as in C, inner declarations override outer ones. What was really nice about BLISS was that all of IF, CASE, WHILE, etc., had values, too. (The value of a loop was "-1" if the loop terminated "normally", and the argument of a "LEAVE" [like C's "break"] if that was used instead.) It is irritating in C that you can't have declarations on the left-hand side of a "," operator... Rob Warnock Systems Architecture Consultant UUCP: {amdcad,fortune,sun}!redwood!rpw3 ATTmail: !rpw3 DDD: (415)572-2607 USPS: 627 26th Ave, San Mateo, CA 94403