Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site watmath.UUCP Path: utzoo!watmath!rbutterworth From: rbutterworth@watmath.UUCP (Ray Butterworth) Newsgroups: net.lang.c Subject: Re: expr?(void):(void) (I was wrong. I've seen the light.) Message-ID: <1983@watmath.UUCP> Date: Fri, 1-Aug-86 17:31:13 EDT Article-I.D.: watmath.1983 Posted: Fri Aug 1 17:31:13 1986 Date-Received: Sat, 2-Aug-86 08:31:03 EDT References: <501@bunny.UUCP> <500@copper.UUCP> <273@watmath.UUCP> <5826@think.COM> <3502@amdahl.UUCP> <927@hoptoad.uucp> Distribution: net Organization: U of Waterloo, Ontario Lines: 113 I've received mail or news from the following people, all strongly protesting that my fix for void functions and the ?: operator was invalid and that the current behaviour of most compilers is correct, and that the proposed ANSI standard is as mixed up as I am. > From: aka@cbrma.UUCP (Andy Kashyap) > From: allbery@ncoast.UUCP (Brandon Allbery) > From: ark@alice.UucP (Andrew Koenig) > From: hamilton@uxc.CSO.UIUC.EDU (Wayne Hamilton) > From: jsdy@hadron.UUCP (Joseph S. D. Yao) > From: > From: seismo!ll-xn!mit-amt!mit-eddie!ci-dandelion!jim (Jim Fulton) > From: whp@cbnap.UUCP (W. H. Pollock x4575 3S235) First I'd like to clear up some confusion. We seem to be arguing about slightly different things. In a statement such as i = e1 ? e2 : e3; there are actually three distinct points where the compiler can make checks. At the "=", it must make sure that the types of "i" and the result of the "?:" expression are the same or at least compatible for an assignment. At the "?" it must make sure that e1 is in fact something that can be tested against 0. At the ":" it must make sure that the types of e2 and e3 are the same or are at least compatible. Now, my "fix" was to the check at the ":". Rather than allowing that the two types may both be void perhaps it would have been better to have done a simple test that any type is allowed as long as they are both the same. After all, the error message at this point does say that the two operands of the ":" are incompatible with each other, when in fact they are not. For instance this fix solves the problem of using "?:" with pointers to void functions that was reported earlier. Even this shouldn't cause people to get upset. The complaints were actually about what happens (or rather doesn't happen) at the "?". This is where the check that people want should go. At this point the compiler could check that the right operand (in the parse tree) is in fact a valid expression and not void. This is the point at which a message such as "'?' operator returns void expression" could be produced. If we added that (see below) as well as leaving in the earlier fix, it would get rid of the misleading "incompatible" message and still produce an error that will keep these people happy. > From: aka@cbrma.UUCP (Andy Kashyap) > A function call is an expression and can, therefore, be used anywhere an > expression can be used. When you declare a function (void), you state that > you intend to use that function as a statement instead, that you do not > intend to use it in any operations. It can now only be used where a statement > can. Keep in mind that an expression is a statement, but NOT vice-versa. > > If you look up the reference section of K&R, somewhere it says something > like this (I don't have my K&R with me): > expression -> expression ? expression : expression > Thus you can not use a statement (ie (void) f1()) where an expression is > expected. That did it. You've finally convinced me of the error of my ways. The "?:" expression has the same value and type as the two expressions around the ":". This type cannot be void. I'm converted. I've seen the light. I'm studing the Bible much more closely. And look what I've found: comma-expression -> expression , expression The type and value of the result are the type and value of the right operand. DMR, Chapter 7, Verse 15. But, isn't that what it says about the "?:" expression too? Hallelujah! I've found a sin in our compiler. It actually allows those evil "void expressions" on the right of a comma. Why, this means we'll have to go back through the last few weeks of news, take all those articles talking about void functions and "?:" and repost them, this time changing the "?:" to ",", since all the arguments in them hold equally well. In the meantime, I urge everyone (well, those mentioned above anyway), to put the follwing fix into their compilers. I'm sure it will find many occurrences of this sin that may have crept into their code over the years. void f3(which) { extern void f1(),f2(); which?f1():f2(); } cc(1) gives an "incompatible types" error. In /usr/src/lib/mip/trees.c add the lines indicated by "->>". ... opact( p ) NODE *p; { ... switch( optype(o=p->in.op) ){ ... case QUEST: /* Look, the two cases are already common. */ case COMOP: /* This must prove the devine intent. */ ->> #ifdef I_HAVE_BEEN_SAVED ->> if (!mt2) uerror("'%s' returns void expression", opts[o]); ->> #endif ... case COLON: if( mt12 & MENU ) return( NCVT+PUN+PTMATCH ); else if( mt12 & MDBI ) return( TYMATCH ); ... else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER ); ->> else if ( mt1==mt2 ) return TYPL; break; case ASSIGN: