Path: utzoo!attcan!uunet!cbmvax!jesup From: jesup@cbmvax.UUCP (Randell Jesup) Newsgroups: comp.sys.amiga Subject: Re: Leo's ANSI C Flame Message-ID: <4179@cbmvax.UUCP> Date: 3 Jul 88 22:19:53 GMT References: <8806292138.AA22025@decwrl.dec.com> <6427@well.UUCP> Reply-To: jesup@cbmvax.UUCP (Randell Jesup) Organization: Commodore Technology, West Chester, PA Lines: 227 In article <6427@well.UUCP> ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) writes: >[ "I sense great frustration, sir." "No shit, Sherlock." ] > > Foom! A 301-line refutation of my ANSI flame! (This article isn't >much shorter.) What it boiled down to was that Randy Meyers was concerned >that there is a great deal of misinformation floating around about Antsy-C, >and wanted to correct it. And he's right. There are some real silly things in ANSI C, but the ones you're pointing out aren't them. I pity people in hearing range when you find out about trigraphs. :-) It could have been worse, noalias bit the big one finally (what, you don't know about noalias? The new untested keyword that required 4 pages to explain, and even the explanation wasn't interpreted the same way by any two compiler writers, let alone users? The thin that made DMR (of K&R fame) say "Noalias must go. That is non-negotiable."?) :-) There might even be features you like, such as prototypes, or maybe the volatile keyword (so you can access hardware safely). >>You are correct. However, such a program is clearly poorly written. [ ... ] > > I never said it was a *good* example. I was illustrating that some >"clever" programmers may be able to find their way to that string constant >and beat on it, thus breaking the optimization. I'd never try anything like >that, largely because it isn't clever enough :-). It's also inherently non-portable. >>Kernighan and Ritchie never guaranteed the string constants were modifiable. > Excuse me? Someone else made the point that you can say: > file = mktemp ("/tmp/ReXXXXX"); > and mktemp() will go in and bash on the string constant (since all >it knows about is the pointer it was passed). I have been led to believe >that ANSI will break this. mktemp assumes you pass it a modifiable string. Remember, ANSI doesn't outlaw modifying string constants, just says the results are implementation- defined. That may be fine in a particular implementation, but it isn't guaranteed to be portable, as a strictly-conforming program is. >>extern int strlen(const char *); /* Required by ANSI */ >> ^^^^^ > What in the name of Zarquon is a *Pascal* keyword doing in a C >program? Does this declaration mean I can only pass string constants to >strlen()? Can't I pass pointer variables anymore? All that means is that strlen won't modify it. It was worse: for a while, strcpy was defined as: extern char *strcpy(noalias char *,noalias const char *); Say that three times quickly. :-) > Coming back to strlen(), I was trying (unsuccessfully, I gather) to >point out that, IMHO, a C compiler really has no business looking at >function calls (which are outside its domain), and trying to figure out what >the programmer *really* wanted to call. If I call strlen(), dammit, I >expect strlen() to be called. I will turn any and all such optimizations >off, since it's too easy for the compiler to foul it up. So turn them off. It's really easy. In fact, they don't even turn on unless you include "string.h", which has the #defines in it. >> register char *p; >> >> p = "abcdefg"; >> >> /* 100,000 lines of code that don't modify p */ >> >> DESC(d, p); > Urp. I believe the optimization is invalid in this case. You have >declared a pointer to a string constant, and are passing the variable to the >macro. The best the compiler can do is detect that p has not changed value, >and drop a constant pointer value (rather than actually pulling it out of p) >into the strlen() argument, and *call strlen()*. You never "pass a variable to a macro". It gets expanded before the compiler sees it (effectively). If the macro includes other macros, fine, they get expanded too. strlen maybe is a bad example. The real win here is with things like strcpy and strcmp, where the inline code is MUCH faster than a function call. > If the compiler were to resolve it to 'DESC (d, "abcdefg")' it would >be an error, since that would compile a *different* copy of the string >constant into memory, unrelated to the one p points to. This is important, >since I may have made a copy of p somewhere, and used the copy to bash on >the constant, making the strlen() optimization invalid. If you did, then the optimization IS invalid, and the compiler has to assume it may be aliased. But the example said that none of the intervening lines used p. This was where noalias was to have come in. If that had been "char *noalias p = ..." (or was that "noalias char *p = ..."?), then you'd be telling the compiler that there are no aliases for what p points to, so it could assume nothing else except p references would bash the string. I think you can see why it got trashed (if you make an error, you get unexplained wrong results from the program with no warnings; and the semantics are much more complicated than I've said.) > Ah! Okay, that was my problem. I thought there was a syntax >required to follow it, like #define. So anyone can do anything they want >with #pragma. It could turn into a can of worms you know... Yeah, but you can strip all pragmas pretty easily. It shouldn't effect the correctness of the resulting program. Pragmas are hints. >> #if LATTICE >> ^^^^^^^ >> #pragma Delete(R0,R1) /* Means delete source file to MANX */ >> #endif >> > I thought ANSI disallowed pre-defined constants or symbols... LATTICE is defined in dos.h. >>Expression control is necessary, but I don't like enforced parentheses >>either. I preferred it when the new unary plus operator controlled >> ^^^^^^^^^^^^^^ >>expression evaluation. [ ... ] > > Unary plus???!!? What's *that* supposed to be for, and how can it >alter expression evaluation? To match unary minus. Yeah, I know it sounds like a nop, and it is, but for a while they hung forced evaluation order on it as well. I think that died the same time as noalias. I don't think the paren ordering of expressions is forced in all cases. > thing = ((i + 4) + 15); > > ...Which means that the compiler first adds four to i, then adds 15 >to it. Wouldn't it be nicer if it just added 19? I think that will remain the default for such cases. Don't worry. You have to try to get paren ordering. > It's funny. When I was briefly exposed to System V UNIX, I noticed >that all the names of the string functions were "wrong". Along comes ANSI, >and I find that the string functions have names remarkably similar to the >broken SYS-V names. There are two camps out there: Sys V, and berkeley. ANSI went with Sys V, and no one is suprised. > o ANSI did not implement binary constants, claiming 'no prior art'. Lots of neat ideas had that happen. Implement them and maybe they'll get in the first revision. (ANSI C92?) > o ANSI held up the finalization of AN-C by flirting with a keyword > named 'noalias', which bought you nothing if you weren't running > on a supercomputer. But it lost you things... > o Dennis M. Ritchie is not on the standards committee, and is also > strangely silent on comp.lang.c with regard to opinions on what > ANSI has done to his language. See above quote. > o ANSI has been focusing their efforts on making the job of the > compiler writer easier, since the committee is populated largely > by purveyors of compilers; and has done little or nothing to > enhance C's usefulness or versatility for the programmer. volatile and noalias and ... make it easier on the compiler writer? You should hear what John Toebes says about ANSI and the work to implement it (which, BTW, takes second place to improving the compiler at Lattice, unless it's something they really want, like prototypes.) > o ANSI-C looks a hell of a lot like Pascal. You seem to have to > talk a lot before you can really say anything. Only if you use all those keywords. In most cases, just ignore them. > o ANSI broke the names of a lot of well-known library functions and > include files. Well known on which systems? That's the problem, every system/OS/ compiler has it's own set of "well-known" includes that don't match many (if any) others. > o ANSI hasn't really resolved a lot of the irritating questions > revolving around C, like what NULL *really* is, or how big a > 'short' or a 'long' *really* are. No, that's well known (except to a few souls who insist the world is flat): NULL is the constant 0, short is <= int which is <= long. I think there MAY be somehthing saying short must be at least 16 bits, and long 32, but I'm really not sure of that at all. > o ANSI acts like 'void' and 'enum' are a new thing. Huh? > Based on what I've heard from a number of individuals, ANSI has a >*lot* of crocks in it that really don't need to be there. My aformentioned >friend made the observation, "If I can't take a valid K&R program that >passes 'lint' and run it through a dumb filter program and get an ANSI >program out the other side, I'll consider ANSI to be a complete and utter >loss." K&R is ancient history. Ever used a REAL K&R compatible compiler? Complete with one name space for ALL structure members? > I'm prepared to sit back and watch to see what happens. In the >meantime, I'm keeping my K&R compiler, since it's worked great so far, and I >like to think I've written some pretty decent code with it. I suspect you have an H&S compiler, not K&R. And no one says everyone MUST implement a full ANSI compiler: Lattice has full ANSI on a back-burner, and some of the ANSI stuff might be controlled by compiler switches. In conclusion: ANSI has some good ideas (which lattice has already stolen, and manx is working on stealing some), and some annoying/bad ideas. I think overall there's more good stuff than bad. (And a lot of the "bad" is merely implementation defined, which means if you don't care about portable code, you've got no problems (assuming the compiler does what you want with such things). -- Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup