ravi@flairvax.UUCP (06/15/83)
A very simple program
#include <stdio.h>
main ()
{
char *c[],*d[];
*c = "i am a string";
*d = "so what";
printf("%s\n",*c);
printf("%s\n",*d);
}
on 4.1bsd produced
so what
so what
whereas the C compiler on the TOPS-20 and other variations of the above
program on 4.1 bsd produced the correct result.
I am curious to find out WHY?.
ravi
Fairchild Research,
Palo Alto,CA.
olson@fortune.UUCP (06/24/83)
#R:flairvax:-13100:fortune:1800003:000:67 fortune!olson Jun 23 20:36:00 1983 See the recent (last 3 days articles on this subject in net.lang.c
rbutterworth@watmath.UUCP (Ray Butterworth) (07/25/86)
> > i = i/2.5; > vs. > > i /= 2.5; So, does anyone have a fix for this bug? I'll trade for a fix for a problem with void functions and the ?: operator. 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 line indicated by "->>". This lets the above code lint and compile ok (and I don't think it causes any new problems). ... opact( p ) NODE *p; { ... switch( optype(o=p->in.op) ){ ... 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:
ark@alice.UucP (Andrew Koenig) (07/26/86)
> So, does anyone have a fix for this bug? > I'll trade for a fix for a problem with void functions and the ?: operator. > > void f3(which) > { > extern void f1(),f2(); > which?f1():f2(); > } > cc(1) gives an "incompatible types" error. As it should. The only thing you're allowed to do with void values is throw them away.
greg@utcsri.UUCP (Gregory Smith) (07/27/86)
In article <5858@alice.uUCp> ark@alice.UucP (Andrew Koenig) writes: >> So, does anyone have a fix for this bug? >> I'll trade for a fix for a problem with void functions and the ?: operator. >> >> void f3(which) >> { >> extern void f1(),f2(); >> which?f1():f2(); >> } >> cc(1) gives an "incompatible types" error. > >As it should. The only thing you're allowed to do with void values >is throw them away. But it is being thrown away. In e1?e2:e3, the contexts of e2 and e3 are inherited from the context of the ?: operator itself. In this case, that is in a 'for effect' or void context, so f1() and f2() should be treated as 'thrown away' too. -- "You'll need more than a Tylenol if you don't tell me where my father is!" - The Ice Pirates ---------------------------------------------------------------------- Greg Smith University of Toronto UUCP: ..utzoo!utcsri!greg
donn@utah-cs.UUCP (Donn Seeley) (07/27/86)
The 'i /= f' bug is fixed in 4.3 BSD. Someone (Hugh Redelmeier) stated earlier that this bug was fixed in System V but some implementations caused side effects in the left hand side to be duplicated. This was one of the problems that made the fix quite difficult for 4.3; the solution was fairly ugly but it works. Essentially what happens is that the compiler front end notices the special situation and avoids 'type balancing'; special code table entries enable the code generator to spot these trees and do the right thing. (This approach is properly termed 'hacking'.) I wasn't able to test this bug on our local System V boxen -- neither of them (SGI Iris, rev 3.4; HP-UX 5.0) have any form of the '/=' fix... The 4.3 compiler no longer generates an 'incompatible types' message for void expressions in the ':' part of a '?' expression -- it prints 'value of void expression used'! Will wonders never Cse, Donn Seeley University of Utah CS Dept donn@utah-cs.arpa 40 46' 6"N 111 50' 34"W (801) 581-5668 decvax!utah-cs!donn
rbutterworth@watmath.UUCP (Ray Butterworth) (07/28/86)
> > void f3(which) > > { > > extern void f1(),f2(); > > which?f1():f2(); > > } > > cc(1) gives an "incompatible types" error. > > As it should. The only thing you're allowed to do with void values > is throw them away. If I'm not throwing them away, what is it you think I'm doing with them? Also, the proposed ANSI draft explicitly states that the second and third operands of ?: may each have (void) type, so I'm not trying anything unusual here.
jcz@sas.UUCP (Carl Zeigler) (07/29/86)
In article <5858@alice.uUCp>, ark@alice.UucP (Andrew Koenig) writes: > > So, does anyone have a fix for this bug? > > I'll trade for a fix for a problem with void functions and the ?: operator > > > > void f3(which) > > { > > extern void f1(),f2(); > > which?f1():f2(); > > } > > cc(1) gives an "incompatible types" error. > > As it should. The only thing you're allowed to do with void values > is throw them away. Scan again, Andrew, the (void) values are being thrown away. -- John Carl Zeigler "Just once I'd like to meet an alien menace SAS Institute Inc. that wasn't impervious to bullets !" Cary, NC 27511 (919) 467-8000 ...!mcnc!rti-sel!sas!jcz
ark@alice.UucP (Andrew Koenig) (07/29/86)
> If I'm not throwing them away, what is it you think I'm doing with them? > Also, the proposed ANSI draft explicitly states that the second and third > operands of ?: may each have (void) type, so I'm not trying anything > unusual here. I think you're using them to form another value. It is irrelevant that you're then throwing that value away. Suppose f() is void and you say: f()+1; Now you're adding 1 to a void and throwing the result away. Should that be permitted? More seriously, I can actually see both sides of the argument. But the construction ...?f():g() where f() and g() are void is close enough to the edge that I wouldn't want to use it in any context where I might ultimately want to run it on a lot of compilers. Why not just say if (...) f(); else g(); ??
jsdy@hadron.UUCP (Joseph S. D. Yao) (07/31/86)
In article <461@watmath.UUCP> rbutterworth@watmath.UUCP (Ray Butterworth) writes: >> > void f3(which) >> > { >> > extern void f1(),f2(); >> > which?f1():f2(); >> > } >> > cc(1) gives an "incompatible types" error. >> As it should. The only thing you're allowed to do with void values >> is throw them away. >If I'm not throwing them away, what is it you think I'm doing with them? >Also, the proposed ANSI draft explicitly states that the second and third >operands of ?: may each have (void) type, so I'm not trying anything >unusual here. My 1984 version of X3J11 (has it been that long?) agrees with K&R that each of the operands must have a value. This makes intuitive sense. The meaning of X ? Y : Z is: an expression whose value is the value of Y, if the value of X is non-zero; otherwise, the value of Z. By this, all three must evaluate to some value. Do you have a more recent edition of X3J11 that r e a l l y lets voids in there? Ugh! (What date?) Besides which, all C compilers until just recently (Lattice, Microsoft) had been written to K&R and v7-s3-s5, not to the ANSI standard. -- Joe Yao hadron!jsdy@seismo.{CSS.GOV,ARPA,UUCP} jsdy@hadron.COM (not yet domainised)
whp@cbnap.UUCP (W. H. Pollock x4575 3S235) (07/31/86)
In article <134@sas.UUCP> jcz@sas.UUCP (Carl Zeigler) writes: > > > > void f3(which) > > > { > > > extern void f1(),f2(); > > > which?f1():f2(); > > > } > > > cc(1) gives an "incompatible types" error. > > > > As it should. The only thing you're allowed to do with void values > > is throw them away. > >Scan again, Andrew, the (void) values are being thrown away. The void values are not thrown away! Remember that (A?B:C) is an expression *returning a value*. C is giving the error because it can't determine the type of the return value. This is clearer in the following: void f3(which) { int f1(); void f2(); int foo; ... foo = which?f1():f2(); ... } which results in the same error message, for the same reason. Another example: f4() { ... return ((void) expression); } Note it doesn't mater what use is made of the return value (in the original example it is thrown on the floor, which is what probably confused some people).
aka@cbrma.UUCP (Andy Kashyap) (07/31/86)
In article <134@sas.UUCP> jcz@sas.UUCP (Carl Zeigler) writes: > In article <5858@alice.uUCp>, ark@alice.UucP (Andrew Koenig) writes: > > > So, does anyone have a fix for this bug? > > > > > > void f3(which) > > > { > > > extern void f1(),f2(); > > > which?f1():f2(); > > > } > > > cc(1) gives an "incompatible types" error. > > > > As it should. The only thing you're allowed to do with void values > > is throw them away. > >Scan again, Andrew, the (void) values are being thrown away. > No they are NOT; the value from the '?:' operator is being thrown away. The '?:' operator expects a non-void value so it can decide 'which' and pass the result to a higher level of expression (in this case there happens to be none). The complaint of "incompatible types" is the result of the '?:' operator expecting a non-void type as arguments and the arguments providing a void type. Wasn't that obvious from the diagnostics??? ;-) To re-phrase, the '?:' doesn't look at its operands (parameters or arguments) as function calls -- they might as well be 'f1()+5' or so -- but as expressions. Therefore it '*RETURNS THE VALUE* of one of its operands depending on the third'. A semantic point of view: 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. The BUG: there ain't none. The FIX: use 'if' instead. - andy kashyap -- +---------------------------------------------------------------------------+ : Jim, what's the value of Pi? : Andy Kashyap : : About 3.14159. Why do you ask, Doctor? : AT&T Bell Labs : : Actually, Captain, the exact value is 3.1415926535...: Columbus OH : : Kirk & McCoy: Shut Up, Spock!!! : ..!cbosgd!cbrma!aka: +---------------------------------------------------------------------------+
dbw@ariel.UUCP (DAVE B. WOOD) (08/01/86)
> construction ...?f():g() where f() and g() are void...
Don't forget side effects.
mikes@apple.UUCP (Mike Shannon) (08/05/86)
Just to be sure we're all on the same wavelength about void expressions with the ?: operator: Consider the case where you're writing a really complex #define macro, and you decide that you'd like some sort of IF statement in it, (take a look at getchar()). Can't you see a case where you might want to call a void function, and then set the value of the #define macro to be a side effect of the function? Sort of like #define foo(c) buffer_empty?fill_buff(),first_char_in_buf:first_char_in_buf I mean, it seems to me that the 'pro' argument is that you get flow of control in #define's. Although when you way that 'void things cannot participate in expressions', a rational person would say that conditional expressions are expressions and so you can't have a void thing in that kind of expression. -- Michael Shannon {apple!mikes}
ark@alice.UucP (Andrew Koenig) (08/06/86)
> Consider the case where you're writing a really complex #define macro, >and you decide that you'd like some sort of IF statement in it, >(take a look at getchar()). Can't you see a case where you might want to >call a void function, and then set the value of the #define macro to be >a side effect of the function? Sort of like >#define foo(c) buffer_empty?fill_buff(),first_char_in_buf:first_char_in_buf No problem using a void as the LHS of a comma operator, just as there's no problem using a void before a semicolon. Of course, you'd better parenthesize: #define foo(c) (empty?(fill(),first):first) Moreover, fill() probably returns a value you don't want to ignore, so maybe you should write it to return either the value of first or an error code. You can then write (empty?fill():first) which avoids the void issue altogether.
apc@cblpe.UUCP (Alan Curtis) (08/20/86)
In article <134@sas.UUCP> jcz@sas.UUCP (Carl Zeigler) writes: > > In article <5858@alice.uUCp>, ark@alice.UucP (Andrew Koenig) writes: > > > So, does anyone have a fix for this bug? > > > > > > void f3(which) > > > { > > > extern void f1(),f2(); > > > which?f1():f2(); > > > } > > > cc(1) gives an "incompatible types" error. > > > > As it should. The only thing you're allowed to do with void values > > is throw them away. > > >Scan again, Andrew, the (void) values are being thrown away. > No, the value of the statement is being thrown away, not the value of the void(s). Would you let me say: . . . f1() + f2(); . . Since I am throwing both away? Alan Curtis
guy@sun.uucp (Guy Harris) (08/21/86)
> No, the value of the statement is being thrown away, not the value > of the void(s). True, but one can imagine the ":" half-operator selecting between one of the two "void" values. One then throws away the value returned by the "?"/":" operator. > > Would you let me say: > . > . > . > f1() + f2(); > . > . > > Since I am throwing both away? No, you're not. You're adding them and then throwing the *sum* away. "void" "value"s can't be added. If you consider "void" to be a sort-of type, the set of whose values is a singleton set, then you can consider boolean_expression ? void_value_1 : void_value_2 to select one of the two "void" values and yield it as a result, so the ":" half-operator, unlike the "+" operator, can act on two "void" values. (Regardless of the value of the <boolean_expression>, the value yielded by the expression will be the same, since <void_value_1> == <void_value_2> == any other void value you can think of.) Think of it this way: "void" values require 0 bits to represent them, since the set of all such values has only one element. As such, "sizeof(void)" should be 0. As such, if you say void x; "x" takes up no memory. Given that, declaring objects of type "void" isn't very useful. An attempt to do so is probably an error, so it is rejected. Also, if objects of type "void" were implemented, most implementations would run the risk of giving it the same address as the next datum declared. So taking the address of a "void" is kind of useless, and so "void *" isn't useful as a true "pointer to void", so it can be overloaded. Also, since all "void" values are the same, an attempt to compare them is probably an error, so "==", etc. aren't defined over the set of "void" values either. -- Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com (or guy@sun.arpa)