Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!samsung!uunet!taumet!steve From: steve@taumet.com (Stephen Clamage) Newsgroups: comp.std.c Subject: Re: call to revolt Message-ID: <782@taumet.com> Date: 26 Jun 91 17:13:06 GMT References: <992@baby.and.nl> Organization: Taumetric Corporation, San Diego Lines: 53 jos@and.nl (J. Horsmeier) writes: >In article rabson@physics.ubc.ca (David Rabson) writes: >[...] >>Outlawing lvalue casts, however, borders on fascism. I have yet to see >>a pre-ansi compiler that fails to treat properly >> void *thing; >> ((int *)thing)++; >>I hereby invite the black-shirts from the ansi camp to explain their >>prejudice against casting lvalues. >Hi there, I'll die if casting lvals is going to be illegal... Sorry your life has to end so soon, but it is not a question of "going to be illegal", but "has always been illegal." This rule is in K&R 1, so it is nothing that the ANSI committee added out of sadism. It is just that many compilers failed to enforce the rule. We have to differentiate between what works on some architectures and what is suitable in a language definition. Besides, you are only presenting the trivial cases. The issue is that a cast is a value conversion, not just a request to treat a region of memory in a different way. Suppose a cast resulted in an lvalue whenever the object of the cast were an lvalue. Then this would be legal: float f; ((double)f)++; Nothing good could come of allowing code like this. So we would have to add an exception, like when the sizes were different. Of course, the representations might be different even when the sizes were the same, so maybe that should be an exception too. It turns into a real mess. The language already supports what you want to do, leaving in the very proper semantic rule that a cast is a value conversion and does not result in an lvalue. To get the effect you want, just take the address, cast the pointer, and dereference. void *thing; (*((int **)&thing))++; This violates no language rules, so long as "thing" was assigned the address of an int. Otherwise, the code is not portable, but happens to work on common architectures. It is hard to write (and read), however. If you do not have religious beliefs which require that ++ be used whenever possible, you can write the above as thing = (int*)thing + 1; which is legal, portable, and readable. In the common case where the illegal example would have been ok, the generated code should be identical with any decent compiler. -- Steve Clamage, TauMetric Corp, steve@taumet.com