maart@cs.vu.nl (Maarten Litmaath) (07/15/89)
henry@utzoo.uucp (Henry Spencer) writes: \In article <2874@solo3.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes: \>Why does the PROGRAMMER have to go through all that trouble? \>I just want to say: \> \> puts(mork == mindy ? "equal" : "unequal"); \> \>Is the ANSI committee trying to tell us the compiler cannot transform the \>equality test into the correct member-by-member comparison code? \ \Yes. Think about unions. Or pointers (do you compare the pointers or \what they point at?). The compiler just doesn't have enough information. I thought of those as well: 1) pointers - They should be compared themselves; if they don't point to the same location, they're unequal by definition; if the data they point at are equal, that's mere coincidence. 2) unions - Compare with the following example: struct foo { char bar[10]; } x, y; (void) strcpy(x.bar, "123456789"); (void) strcpy(y.bar, "987654321"); (void) strcpy(x.bar, "zork"); (void) strcpy(y.bar, "zork"); puts(x == y ? "yes" : "no"); I say the output should be "no", because all 10 bytes in `bar' must be compared. (The array needn't be a string at all! I might have used it to store small integers.) If you want to get "yes", you have to make sure there's no garbage at the end of `bar', i.e. you must clear the unused part explicitly. Unions can be dealt with likewise. I KNOW these two specifications might cause some surprises in actual code, but: 1) Compare with this little gem to confuse Pascal programmers: if ("string" != "string") puts("how weird!"); 2) The following example shows how useful struct comparison could be: struct complex { int real; int imag; } z, w; ... if (z == w) ... -- "... a lap-top Cray-2 with builtin |Maarten Litmaath @ VU Amsterdam: cold fusion power supply" (Colin Dente) |maart@cs.vu.nl, mcvax!botter!maart
henry@utzoo.uucp (Henry Spencer) (07/16/89)
In article <2878@kappl.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes: >\Yes. Think about unions. Or pointers (do you compare the pointers or >\what they point at?). The compiler just doesn't have enough information. > >I thought of those as well: >1) pointers - They should be compared themselves; if they don't point to > the same location, they're unequal by definition; if the data they > point at are equal, that's mere coincidence. For "char *" in particular, comparing the pointers themselves usually won't be what's wanted. Of course, if the compiler wants to try to compare the chars, then it has to know whether the pointers really point to strings... and it doesn't. Same problem with char arrays inside a struct -- is that a string (i.e. stuff past the NUL doesn't count) or not? > If you want to get "yes", you have to make sure there's no garbage > at the end of `bar', i.e. you must clear the unused part explicitly. > Unions can be dealt with likewise. How? There *isn't* any (reliable) way to get at the unused part. You could assign the same constant to the longest member in each union -- but in general you don't know which member *is* longest. Oh sure, these things can be dealt with... but every time you deal with one, you reduce the utility of the feature by placing more and more restrictions on how it can be used and what answers it gives. It's not worth it. >1) Compare with this little gem to confuse Pascal programmers: > > if ("string" != "string") > puts("how weird!"); Actually the answer to this one is implementation-defined, to make things still weirder. ANSI C can combine string literals. But consider, say, "if a<b and c<d then ..." in Pascal -- guaranteed to surprise a C programmer. This sort of cross-language comparison is silly; all it proves is that most languages have surprises for the unwary, and treating C as it were Pascal -- or vice versa -- is foolish. >2) The following example shows how useful struct comparison could be: > struct complex { > int real; > int imag; > } z, w; > if (z == w) ... Sigh, this one is pretty standard. It's also dumb; do you then want to define struct add and subtract as well? It's also not a particularly good idea: suppose I change to a polar form, where the representation of a given complex number is not unique? The right answer to this one is C++, where you can *define* what the operators mean. To quote Dennis Ritchie: "if you want PL/I, you know where to find it". -- $10 million equals 18 PM | Henry Spencer at U of Toronto Zoology (Pentagon-Minutes). -Tom Neff | uunet!attcan!utzoo!henry henry@zoo.toronto.edu