limes@ouroborous (Greg Limes) (10/18/88)
In article <6945@cdis-1.uucp>, tanner@cdis-1 (Dr. T. Andrews) writes: >It is also possible that compiler writers will get the "for" loop >handling wrong. It is unwise to depend on "for" loops in portable >code. Use a "while" loop instead. It is possible for compiler writers to get lots of things wrong; breaking something as fundamental as a "for" statment results in an unusable compiler. It is, well, kind of basic to the language. Dr. Andrews, can you provide an example of a compiler in common use that manages to get the for loop wrong? I will gladly make a note of such and stay away from them (and any other software produced by their writers). Portability usually includes such wild concepts as readability and maintainability (at least in my mind), and a properly organized "for" loop becomes a bit more opaque when reduced to a "while". --
tim@crackle.amd.com (Tim Olson) (10/19/88)
In article <73408@sun.uucp> limes@ouroborous (Greg Limes) writes: | In article <6945@cdis-1.uucp>, tanner@cdis-1 (Dr. T. Andrews) writes: | >It is also possible that compiler writers will get the "for" loop | >handling wrong. It is unwise to depend on "for" loops in portable | >code. Use a "while" loop instead. | | It is possible for compiler writers to get lots of things wrong; breaking | something as fundamental as a "for" statment results in an unusable | compiler. It is, well, kind of basic to the language. | | Dr. Andrews, can you provide an example of a compiler in common use that | manages to get the for loop wrong? I will gladly make a note of such and stay | away from them (and any other software produced by their writers). Didn't anyone else see what Dr. Andrews was pointing out? Saying that you should avoid the construct 1["string"] is *like* saying you should avoid a for loop, because both are fundamental constructs that a broken C compiler may not implement correctly. Avoiding something fundamental just because some compiler somewhere gets it wrong is no excuse -- FIX THE COMPILER. -- Tim Olson Advanced Micro Devices (tim@crackle.amd.com)
limes@ouroborous (Greg Limes) (10/20/88)
In article <6945@cdis-1.uucp>, tanner@cdis-1 (Dr. T. Andrews) writes: >It is unwise to depend on "for" loops in portable >code. Use a "while" loop instead. In article <73408@sun.uucp> limes@ouroborous (Greg Limes) writes: >Dr. Andrews, can you provide an example of a compiler in common use that >manages to get the for loop wrong? In article <23299@amdcad.AMD.COM>, tim@crackle (Tim Olson) writes: >Didn't anyone else see what Dr. Andrews was pointing out? Saying that >you should avoid the construct 1["string"] is *like* ... I may have put my foot in the middle of that one, but maybe not. On the other hand, it is easier to simply say that I was asleep at the keyboard, then to point out the basic difference between getting a "for" construct wrong (something basic to the language and hard to get wrong) in a compiler, and failing to support subscripting an integer by a pointer (something a bit less basic, and in fact rather arcane, that may fall by the wayside if there are a lot of complex issues about pointers). So, sorry for being asleep at the keyboard. -- Greg Limes [limes@sun.com] semper ubi, sub ubi
davidsen@steinmetz.ge.com (William E. Davidsen Jr) (10/20/88)
In article <23299@amdcad.AMD.COM> tim@crackle.amd.com (Tim Olson) writes: | Didn't anyone else see what Dr. Andrews was pointing out? Saying that | you should avoid the construct 1["string"] is *like* saying you should | avoid a for loop, because both are fundamental constructs that a broken | C compiler may not implement correctly. Avoiding something fundamental | just because some compiler somewhere gets it wrong is no excuse -- FIX | THE COMPILER. I would suggest that there is a very good reason to avoid int[ptr], being that it's hard to read. Obviously it's part of the language, but is there any reason to use it other than to prove how well you understand C? That's real question, I would be pleased to learn that there really is some benefit, but I don't see much between int[prt], ptr[int] and *(ptr+int) other than readability. Obviously "string"[int] is legal, too, but somewhat less than readable to the casual programmer. -- bill davidsen (wedu@ge-crd.arpa) {uunet | philabs}!steinmetz!crdos1!davidsen "Stupidity, like virtue, is its own reward" -me
ts@cup.portal.com (Tim W Smith) (11/01/88)
I don't know about i[ptr] being less readable than ptr[i]. Most people I have heard would say when describing an algorithm in English, "Then you take the ith element of the array and multiply by foo". i[array]*foo has the words in C in the same order they would be spoken. Tim Smith
hjm@cernvax.UUCP (Hubert Matthews) (11/04/88)
In article <10742@cup.portal.com> ts@cup.portal.com (Tim W Smith) writes: >I don't know about i[ptr] being less readable than ptr[i]. Most people I >have heard would say when describing an algorithm in English, "Then you take >the ith element of the array and multiply by foo". i[array]*foo has the >words in C in the same order they would be spoken. > > Tim Smith Take a look at Knuth. He uses a notation like next(a) to represent the C statement a.next. His argument goes something like this. The function next() is applied to a variable argument - next(a) or next(b) - just like good ol' array indexing in FORTRAN - array(i). Well, why not? BCPL made it very obvious that a[i] and i[a] are the same; it used (uses?) a!i to mean *(a+i). This works fine even for structure access, until you have strong typing. Guess what BCPL didn't have? I, personally, IMHO, would be happy with a[next] for structure access or a.i for array access. Isn't it all really the same and just a matter of conditioning? As I said, it's not obvious how strong typing would work in such a language, but it would eliminate one more thing for the compiler writers to have to do *and get right*. :-) -- Hubert Matthews
ok@quintus.uucp (Richard A. O'Keefe) (11/08/88)
In article <867@cernvax.UUCP> hjm@cernvax.UUCP (Hubert Matthews) writes: >I personally, IMHO, would be happy with a[next] for structure access or >a.i for array access. Isn't it all really the same and just a matter >of conditioning? As I said, it's not obvious how strong typing would >work in such a language, but it would eliminate one more thing for the >compiler writers to have to do *and get right*. :-) In POP, arg.fn and fn(arg) are merely syntactic variants, so one can write record.field -> array(subscript); or field(record) -> subscript.array; and it's all the same thing. How would string typing work? Just like it always did: the information comes from the (bindings of) the identifiers, not the punctuation marks.
dsb@Rational.COM (David S. Bakin) (11/09/88)
[What's going on? The article I'm replying to was signed by Chris Torek of uunet!mimsy!chris but the headers say it is from ok@quintus.uucp???] In article <645@quintus.UUCP>, ok@quintus (Richard A. O'Keefe) writes: >In article <192@libove.UUCP> root@libove.UUCP (Jay M. Libove) writes: >>Looking at the above, I read it to be "shift an n-bit integer n bits left" >>... Now, why is there any question as to the result? > >Because different machines implement shift-left differently. > > ... [omitted] > >On the VAX, the result of shifting by the (not known to be constant) >value 32 is the same as the result of shifting by zero, because the VAX >looks only at the 5 lowest order bits of the shift count. It does this >so that right shifts can be done with negative left shifts. >-- >In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) >Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris I don't get it. The operator << is defined in C as a left shift, what does that have to do with a particular VAX instruction, ASHL, that happens to mask its operand to the low-order 5 bits. Doesn't this merely mean that on the VAX when the argument of the left shift is not a known constant that the single instruction ASH sequence must be replaced by a multiple instruction sequence that does the right thing? -- Dave ---------------------------------------------------------- Dave Bakin (408) 496-3600 c/o Rational; 3320 Scott Blvd.; Santa Clara, CA 95054-3197 Internet: dsb@rational.com Uucp: ...!uunet!igor!dsb
ok@quintus.uucp (Richard A. O'Keefe) (11/09/88)
In article <339@igor.Rational.COM> dsb@Rational.COM (David S. Bakin) continues asking about "<<". >The operator << is defined in C as a left shift, ... Nope. << is defined to be whatever C defines it to be, and C leaves it as vague as possible to make it easy for compiler writers to generate fast code. (There is something just slightly crazy about this.) It has nothing to do with the VAX as such. We can define shifting for signed integers as X << Y = floor(X * 2**Y) which definition works beautifully for all values of X and Y. Alas, that's not what the hardware does on _any_ machine that I know of (the VAX comes *closest*.) Some machines take the bottom 5 bits. Some take the bottom 6. Some haven't _got_ a left shift instruction. (For example, on the M88000, the simplest translation of X<<Y yields the result X&1 when Y==32.) If you want to make sure that you will get the result you expect, define BITS_PER_BYTE suitably and write result = Y >= BITS_PER_BYTE*sizeof X ? 0 : X>>Y; (assuming that you are happy to have result undefined when Y < 0).
henry@utzoo.uucp (Henry Spencer) (11/10/88)
In article <339@igor.Rational.COM> dsb@Rational.COM (David S. Bakin) writes: >I don't get it. The operator << is defined in C as a left shift, what >does that have to do with a particular VAX instruction, ASHL, that happens >to mask its operand to the low-order 5 bits. Doesn't this merely mean that >on the VAX when the argument of the left shift is not a known constant that >the single instruction ASH sequence must be replaced by a multiple instruction >sequence that does the right thing? The point is precisely that one would prefer to avoid this, for the sake of (whisper it) efficiency. There are quite a number of places where the semantics of C are deliberately machine-specific, to permit implementors to do things the most efficient way rather than having to take a performance hit from doing them a standard way. Such flexibility is generally made available either because the efficiency impact of not doing so is major (e.g. size of int) or because the semantics appear to be unimportant for well-written programs (e.g. the order of side effects in an expression). Shift counts equal to the word size are generally considered a case of the latter, with some of the former stirred in. -- The Earth is our mother. | Henry Spencer at U of Toronto Zoology Our nine months are up. |uunet!attcan!utzoo!henry henry@zoo.toronto.edu
guy@auspex.UUCP (Guy Harris) (11/10/88)
>I don't get it. The operator << is defined in C as a left shift, what >does that have to do with a particular VAX instruction, ASHL, that happens >to mask its operand to the low-order 5 bits. Doesn't this merely mean that >on the VAX when the argument of the left shift is not a known constant that >the single instruction ASH sequence must be replaced by a multiple instruction >sequence that does the right thing? More precisely, "<<" is defined as a left shift that does unspecified things if the shift count is larger than the size of the (appropriately promoted) left-hand operand. Thus, the single VAX ASHL instruction implements what various language specs say "<<" means, and a left-shift instruction that *didn't* mask the shift count would also do so.
smryan@garth.UUCP (Steven Ryan) (11/10/88)
>- just like good ol' array indexing in FORTRAN - array(i). Well, why >not? BCPL made it very obvious that a[i] and i[a] are the same; it To an optimiser in a language with real arrays, they are not the same. In such languages, lwb a<=i<=upb a so that the location is constrained to the region labeled a. This permits optimisers to make assumptions about whether two memory references can interfere. >used (uses?) a!i to mean *(a+i). This works fine even for structure >access, until you have strong typing. Guess what BCPL didn't have? I, >personally, IMHO, would be happy with a[next] for structure access or >a.i for array access. Isn't it all really the same and just a matter How would you parse that? Fields and subscripts have different syntax, although the concept are similar, to make context-free parsing possible. -- -- s m ryan -------------------------------------------------------------------------------- As loners, Ramdoves are ineffective in making intelligent decisions, but in groups or wings or squadrons or whatever term is used, they respond with an esprit de corps, precision, and, above all, a ruthlessness...not hatefulness, that implies a wide ranging emotional pattern, just a blind, unemotional devotion to doing the job.....
ok@quintus.uucp (Richard A. O'Keefe) (11/10/88)
In article <1811@garth.UUCP> smryan@garth.UUCP (Steven Ryan) writes: >>personally, IMHO, would be happy with a[next] for structure access or >>a.i for array access. Isn't it all really the same and just a matter > >How would you parse that? Fields and subscripts have different syntax, >although the concept are similar, to make context-free parsing possible. Some languages use different syntax for fields and arrays, just as some languages (e.g. C, Pascal, Algol) use different syntax for arrays and other functions and some (e.g. Fortran, ADA) don't. Context-free parsing has nothing to do with the case. In the usual mathematical model of records, "fields" are projection FUNCTIONS. That is, given type node = (data: int, next: link) we have two functions data: node->int, next: node->link. And an array is a function which maps its index set to its element set, e.g. var data: array[node] of int; next: array[node] of link; Whether one writes n.data "field" data[n] "array" data(n) "function" is a matter of taste. You have to check "data" in the symbol table anyway, to make sure that it is a valid field name (or array name, or function name). Some people like to think of fields, arrays, and functions as distinct, and prefer a notation which makes that explicit. Some people like to think of them all as functions, and prefer a notation which lets them change the implementation without having to rewrite all their code. Have you never found it frustrating that C will let you write macros that look like functions, but not macros that look like arrays or fields?
dsb@Rational.COM (David S. Bakin) (11/11/88)
Well I've read several responses to my innocent and IMHO reasonable "assertion" that C's << operator was a left shift. All pointed out that it is a machine-dependent left shift and deliberately so in the name of efficiency. This means two things to me. First, I have to reread the C manuals I have verrry carefully. And second, my original opinion was right: C is no more than an assembly language with extra whitespace and slower language translators. :-) -- Dave ---------------------------------------------------------- Dave Bakin (408) 496-3600 c/o Rational; 3320 Scott Blvd.; Santa Clara, CA 95054-3197 Internet: dsb@rational.com Uucp: ...!uunet!igor!dsb
chris@mimsy.UUCP (Chris Torek) (11/11/88)
In article <342@igor.Rational.COM> dsb@Rational.COM (David S. Bakin) writes: >Well I've read several responses to my innocent and IMHO reasonable >"assertion" that C's << operator was a left shift. All pointed out >that it is a machine-dependent left shift and deliberately so in the >name of efficiency. > >This means two things to me. First, I have to reread the C manuals >I have verrry carefully. And second, my original opinion was right: >C is no more than an assembly language with extra whitespace and >slower language translators. :-) To some extent, yes. But this is true of most languages. There are remarkably few languages in which `*' (or whatever the local symbol may be) *really* means `multiply', for instance. It usually means `choose the appropriate MUL instruction/subroutine and let the chips fly where they may'---often into the bit bucket. There are a number of languages where for i:integer from 0 to 60000 do ... rof runs forever on a 16-bit machine. This deviation from the `mathematically proper' behaviour is virtually always done for `efficiency'. There is often some attempt at allowing runtime error checking (via, e.g., exceptions), but it is also often weak (which arithmetic exceptions are *guaranteed* in Ada? PL/I?). There *are* languages in which `*' really means `multiply'. One of these is even old enough for most people to have heard of it :-) ---Lisp. If you multiply big numbers, you get back a bignum, not an overflow. If you shift n left s, you get n times two-sup-s. You also pay a penalty in efficiency---so much so that the local Lisp dialect usually provides an `I think this cannot overflow so use the MUL instruction' variant. Type-inferencing (and range-inferencing) languages or compilers sometimes do this for you in `safe' ways. More of these sorts of languages are appearing all the time. These are the real `high level' languages. They are still largely pure research vehicles. Languages of the other sort, including C, Pascal, Modula, FORTRAN, etc., are designed as a compromise between `what the machine really does' and `what abstractions programmers would like the machine to do'. The real differences between `low' and `high' level languages are not in their syntaxes, but rather in how well they insulate the programmer from the shocks found down on the bare metal. The insulation is sometimes quite thin, and it is your job as a programmer to know exactly where and how much. When you said: >... I have to reread the C manuals I have verrry carefully. you were right. You should have done that earlier (but with the dpANS you will have to do it again anyway---some of that insulation has been moved around). If you write anything more than toy programs, know your languages' weak spots. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
john@frog.UUCP (John Woods) (11/14/88)
In article <14488@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes: > In article <342@igor.Rational.COM> dsb@Rational.COM (David S. Bakin) writes: > >... I have to reread the C manuals I have verrry carefully. > > you were right. You should have done that earlier (but with the dpANS > you will have to do it again anyway---some of that insulation has been > moved around). > I thought I felt a Draft in here... -- John Woods, Charles River Data Systems, Framingham MA, (617) 626-1101 ...!decvax!frog!john, john@frog.UUCP, ...!mit-eddie!jfw, jfw@eddie.mit.edu Science does not remove the TERROR of the Gods!