jas@ernie.Berkeley.EDU (Jim Shankland) (04/18/89)
In article <628@gonzo.UUCP> daveb@gonzo.UUCP (Dave Brower) writes: [A long diatribe against use of the comma operator in all contexts except macro bodies, and, sometimes, "for" loop initialization and continuation.] Granted, everyone should write code that is easily understandable by others. Granted, also, that the way to do that depends on idioms in common use in a particular language: constructs that are common usage in, e.g., LISP, may be obscure in C. Granted, finally, that it is quite possible to write obscure C code by using the comma operator (and in countless other ways). I still suggest that a C programmer who understands: (A) if (x->in_use) { x++; y++; } but who is mystified by: (B) if (x->in_use) x++, y++; had best be investigating alternate career paths. The goal daveb@gonzo is pursuing is an admirable one: how can we get programmers, especially masses of programmers, to write code that is correct, understandable, and modifiable by others, in reasonable time? It is certainly one of the most important questions in programming, and answers have been slow in coming. I understand and sympathize with the temptation to tilt at windmills; but it won't kill the dragons. The world is full of bad programmers. A magic potion that would turn them all into good programmers would be a useful thing, indeed. Brings to mind the (surely apocryphal) story about the ne'er-do-wells who finagled an NSF grant to research ways to turn cow shit into butter. Having partied away the entire grant, they applied for supplemental funds, with the argument: "We've gotten it to spread like butter, now we need more money to work on the taste." Exorcising the comma operator from bad code may make it spread better. The taste, alas, remains unchanged. Jim Shankland jas@ernie.berkeley.edu "Blame it on the lies that killed us, blame it on the truth that ran us down"
bill@twwells.uucp (T. William Wells) (04/19/89)
In article <28831@ucbvax.BERKELEY.EDU> jas@ernie.Berkeley.EDU (Jim Shankland) writes: : I still suggest that a C programmer who understands: : : (A) if (x->in_use) : { : x++; : y++; : } : : but who is mystified by: : : (B) if (x->in_use) : x++, y++; : : had best be investigating alternate career paths. The thing that is wrong with the latter has little to do with mystification. What is wrong is that, for rapid and accurate understanding of code, one should avoid appearing to do more than one thing at a time. In other words, the physical layout of the code should make each thing being done appear distinct from all the other things being done. How often have you been burned by missing the second part of a comma operator? How frequently have you missed the assignment is some idiocy like: foo(<long---complicated---expression, ((bletch = 1) * glorch); And how often have you missed the significance of an expression that is pasted on the end of an if? As in awful code like: if (expression) { statement; statement; /*!*/ } Look rapidly at the examples following the form feed. Which one would you understand most quickly? And which one, after a quick glance, would you believe you had understood more accurately? if (!(fp1 = fopen(name1, "r")) || !(fp2 = fopen(name2, "r"))) { error(); } if ( !(fp1 = fopen(name1, "r")) || !(fp2 = fopen(name2, "r"))) { error(); } The point is that the latter makes it clear that two different things are happening. The former you have to figure this out for yourself. The cost is in time, and if you are just skimming the code, in immediate comprehension. Of course, such differences are trivial in any given fragment of code, but when carried out throughout the program, they can make the difference between code that is easy to understand and code whose reading feels like wading through a swamp. --- Bill { uunet | novavax } !twwells!bill (BTW, I'm may be looking for a new job sometime in the next few months. If you know of a good one where I can be based in South Florida do send me e-mail.)
rupley@arizona.edu (John Rupley) (04/19/89)
In article <28831@ucbvax.BERKELEY.EDU>, jas@ernie.Berkeley.EDU (Jim Shankland) writes: > The world is full of bad programmers. A magic potion that would turn > them all into good programmers would be a useful thing, indeed. > Brings to mind the (surely apocryphal) story about the ne'er-do-wells > who finagled an NSF grant to research ways to turn cow shit into butter. > Having partied away the entire grant, they applied for supplemental > funds, with the argument: "We've gotten it to spread like butter, > now we need more money to work on the taste." Ah, but the __true__ story is even better...... At a meeting of the National Academy, in 1967 I believe, there was a panel discussion with several significant bureaucrats from the NSF and NIH. They floated the idea that science funding should be partly if not largely through block grants to Universities, whose administrators would have the power to distribute the funds. This horrifying concept prompted a response from Kistiakowsky (kinetics, explosions, atom bomb, Eisenhower, science advisor -- for those too young in years to remember). He rose from the audience and said that the proposal reminded him of conversations he had had with a Soviet Academician. Several years previously, the Academician had described the Russian project to convert shit into butter. Subsequently, Kistiakowsky recounted, the Academician told him the project was half completed -- they had learned to spread it on bread. Metaphor complete, Kistiakowsky returned to his seat. John Rupley rupley!local@megaron.arizona.edu
crossgl@ingr.com (Gordon Cross) (04/20/89)
In article <828@twwells.uucp> bill@twwells.UUCP (T. William Wells) writes: > >The thing that is wrong with the latter has little to do with >mystification. What is wrong is that, for rapid and accurate >understanding of code, one should avoid appearing to do more than one >thing at a time. > >In other words, the physical layout of the code should make each thing >being done appear distinct from all the other things being done. I'd like to make one small observation about Mr. Wells' above comment. In certain cases where execution speed is of primary importance and you don't have the time or energy to code in assembler (God forbid!) the vast majority of compilers (that I've seen anyway) tend to generate better code for a single complex expression that accomplishes multiple (related) tasks than for the equivalent multiple simple expressions. For example an "insert into doubly linked list" operation on my compiler: This one used 4 instructions - (new->next = next)->prev = (new->prev = prev)->next = new; This one used 7 instructions - new->next = next; new->prev = prev; next->prev = new; prev->next = new; -- Gordon Cross UUCP: uunet!ingr!crossgl "all opinions are 111 Westminister Way INTERNET: crossgl@ingr.com mine and not those Madison, AL 35758 MA BELL: (205) 772-7842 of my employer."
bill@twwells.uucp (T. William Wells) (04/21/89)
In article <28847@ucbvax.BERKELEY.EDU> jas@ernie.Berkeley.EDU (Jim Shankland) writes: : In article <828@twwells.uucp> bill@twwells.UUCP (T. William Wells) writes: : [again saying the comma operator is unclear, because it doesn't adequately : separate two distinct operations; also, giving a couple of examples : of slightly obscure code, with suggestions for improving readability.] : : I claim that when the operations are closely related, such as walking : down two arrays in lockstep, the comma is adequate separation, and is : arguably clearer -- and certainly more concise -- than a compound statement. It depends. I often use various devices that break one or more "rules". E.g., the notion of splitting up separate operations might well be thought to require as a rule that one put exactly one operation per line. However, there are many cases where I don't do this. One of my favorite examples is in a state machine, one which looks like this: while (1) { switch (state) { case ST_FOO: act_foo(); state = ST_BAR; continue; case ST_BAR: act_bar(); state = ST_BLETCH; continue;' ... case ST_DONE: break; } break; } I claim that, if it can be made clear in this way, that it is better than the "put one thing on one line" approach. Certainly, I see it that way. : I was really trying to make a meta-point: writing good, clear code : is a lot more complicated than following a few simple rules. Rules : like, "Don't use the comma operator" are neither necessary nor sufficient : to enforce good coding. Effort spent inventing and enforcing such rules : is better spent elsewhere. I agree with all but the last sentence. There are two distinct reasons: 1) Having a set of default rules means that one doesn't have to spend lots of time re-inventing the wheel. One just writes the code according to the standard and, only when that appears inadequate, does one have to spend the time to design the appropriate layout of your text. 2) Having a set of default rules also results in consistency in the final product. This consistency is important in that it makes maintenance easier and more reliable. Since there are many essentially arbitrary choices to make in code layout, if there were no standards, there would be many different ways of doing exactly the same things, resulting in more difficult to understand code. I wrote a coding standard document for Proximity; here is its introduction: This document contains a description of Proximity's C coding conventions and practices. It describes rules for naming files and symbols, and outlines the format of source and include files. It also discusses the use of Proxlib and the standard C library routines. The benefits of these coding practices are threefold: the code is (1) more easily understandable, (2) more easily ported between systems, an important feature in Proximity products, and (3) more likely to work the first time and be free of hidden bugs. These rules should be followed in most code, but unusual situations may require unusual code. When breaking these rules, unless it is obvious from the context, you must include a comment stating why you broke them. This reason must be equivalent to ``Something bad will happen if I follow the rule'' rather than ``Something good will happen if I break the rule''. Thus, if you have a piece of code whose fast execution is essential to the quality of the product in which it is embedded, it would be proper to include a rule-violating hack. If, on the other hand, you have a neat trick which would make the program faster or smaller, when such is unnecessary, but which would break one of these rules or which would make the program unclear: DON'T DO IT! There are situations when it would be a good idea to modify some of these rules. If you run into one of these, discuss it with your project leader (or the head of the software department if you are the project leader). Then, assuming you can agree on the modification, go ahead and use your modified rule, but until you have had this document updated, comment your use. Also, tell the person responsible for this document about the rule change. --- Bill { uunet | novavax } !twwells!bill (BTW, I'm may be looking for a new job sometime in the next few months. If you know of a good one where I can be based in South Florida do send me e-mail.)
bill@twwells.uucp (T. William Wells) (04/21/89)
In article <5053@ingr.com> crossgl@ingr.UUCP (Gordon Cross) writes:
: I'd like to make one small observation about Mr. Wells' above comment. In
: certain cases where execution speed is of primary importance and you don't
: have the time or energy to code in assembler (God forbid!) the vast majority
: of compilers (that I've seen anyway) tend to generate better code for a single
: complex expression that accomplishes multiple (related) tasks than for the
: equivalent multiple simple expressions. For example an "insert into doubly
: linked list" operation on my compiler:
:
: This one used 4 instructions -
:
: (new->next = next)->prev = (new->prev = prev)->next = new;
:
: This one used 7 instructions -
:
: new->next = next;
: new->prev = prev;
: next->prev = new;
: prev->next = new;
But, counterintuitively, one VAX compiler given the following:
x = y = z = 0;
generated worse code than
x = 0;
y = 0;
z = 0;
Why? Because the compiler chose to interpret the first one according
to its letter rather than its spirit, generating:
move z,0
move y,z
move x,y
instead of the better:
move z,0
move y,0
move x,0
or even:
move register,0
move z,register
move y,register
move x,register
And the compiler that did this would have compiled both of the
examples with only four instructions.
The moral? Unless you a) have reason to believe that the speed is
going to make a difference, and b) are willing to read assembly code
to verify that your coding hack really makes a difference, follow
your style rules rather than doing speed hacks.
---
Bill { uunet | novavax } !twwells!bill
(BTW, I'm may be looking for a new job sometime in the next few
months. If you know of a good one where I can be based in South
Florida do send me e-mail.)
bobmon@iuvax.cs.indiana.edu (RAMontante) (04/22/89)
Just to keep this thread from dying its well-deserved death . . . . Is there a circumstance in which the comma operator is required, where the compound statement cannot be broken into multiple statements?
gwyn@smoke.BRL.MIL (Doug Gwyn) (04/22/89)
In article <19913@iuvax.cs.indiana.edu> bobmon@iuvax.cs.indiana.edu (RAMontante) writes: >Is there a circumstance in which the comma operator is required, where >the compound statement cannot be broken into multiple statements? You've got to be kidding -- a comma expression is an expression, whereas multiple statements are not an expression. Thus the comma operator is useful in contexts where semicolon-terminated statements would not be. Look at the definition of putc() in most implementations of <stdio.h> for an example.
bobmon@iuvax.cs.indiana.edu (RAMontante) (04/23/89)
gwyn@brl.arpa (Doug Gwyn) <10092@smoke.BRL.MIL> : - [ me ] ->Is there a circumstance in which the comma operator is required, where ->the compound statement cannot be broken into multiple statements? - -You've got to be kidding -- a comma expression is an expression, -whereas multiple statements are not an expression. Thus the comma -operator is useful in contexts where semicolon-terminated statements -would not be. Look at the definition of putc() in most implementations -of <stdio.h> for an example. "You've got to be kidding?" In fact someone else suggested getchar() as an example. Looking at the Turbo C stdio.h, and the ULTRIX v1.7 stdio.h, I find that neither one uses a comma in getc, getchar, putc, putchar, or anywhere else, except to separate parameters. Nonetheless I think I get the idea, but that doesn't mean that the code wouldn't work without the comma (does it?) -- couldn't the same semantics be reproduced by a series of statements culminating in the final expression of the parentheses (presumably for assignment purposes)? I said "required", not "useful".
bill@twwells.uucp (T. William Wells) (04/23/89)
In article <19913@iuvax.cs.indiana.edu> bobmon@iuvax.cs.indiana.edu (RAMontante) writes:
: Is there a circumstance in which the comma operator is required, where
: the compound statement cannot be broken into multiple statements?
Certainly, though I'd not say "required", just "much better
programming": in macros and in the initialization and update parts of
for statements. And I'm sure I could think of a few more if I spent
the time.
---
Bill { uunet | novavax } !twwells!bill
(BTW, I'm may be looking for a new job sometime in the next few
months. If you know of a good one where I can be based in South
Florida do send me e-mail.)
gwyn@smoke.BRL.MIL (Doug Gwyn) (04/23/89)
In article <19926@iuvax.cs.indiana.edu> bobmon@iuvax.cs.indiana.edu (RAMontante) writes: >I find that neither one uses a comma in getc, getchar, putc, putchar, or >anywhere else, except to separate parameters. Ok, I picked a bad example. However, many macros need to accomplish more than one thing and cannot do so without the aid of some such trickery as ((expr1) & 0 | (expr2)) which is more simply expressed as (expr1, expr2) >Nonetheless I think I get the idea, but that doesn't mean that the code >wouldn't work without the comma (does it?) -- couldn't the same semantics >be reproduced by a series of statements culminating in the final >expression of the parentheses (presumably for assignment purposes)? No! A series of statements cannot be used as a subexpression. Of course -- as I just demonstrated -- there are ways to avoid ever using a comma operator, but then all you really need is a Turing machine, right? So why does C provide more than the logical minimum? It's because it was designed to be USED for real programming, and matters of convenience are quite relevant for that.
sho@pur-phy (Sho Kuwamoto) (04/23/89)
In article <19926@iuvax.cs.indiana.edu> bobmon@iuvax.cs.indiana.edu (RAMontante) writes:
<gwyn@brl.arpa (Doug Gwyn) <10092@smoke.BRL.MIL> :
<< [ me ]
<<<Is there a circumstance in which the comma operator is required, where
<<<the compound statement cannot be broken into multiple statements?
<<
<<You've got to be kidding << a comma expression is an expression,
<<[..]
<[..]
<Nonetheless I think I get the idea, but that doesn't mean that the code
<wouldn't work without the comma (does it?) -- couldn't the same semantics
<be reproduced by a series of statements culminating in the final
<expression of the parentheses (presumably for assignment purposes)?
When it comes right down to it, there are lots of unneccessary features.
for, while, case, do while, the entire preproccessor, array indexing,
->, ?:, structs, unions, etc. All of these could be done with goto and
explicit pointer manipulation, etc., if you wanted to. But why?
As for another example where you could use the comma operator usefully,
how about...
for(i=0, p=head; p->next != NULL; i++, p=p->next)
or something.
-Sho
wietse@wzv.UUCP (Wietse Z. Venema) (04/23/89)
bobmon@iuvax.cs.indiana.edu (RAMontante) writes: >Is there a circumstance in which the comma operator is required, where >the compound statement cannot be broken into multiple statements? "... in macros where a multistep computation has to be a single expression." K&R second edition, page 63. -- work: wswietse@eutrc3.uucp | Eindhoven University of Technology work: wswietse@heitue5.bitnet | Mathematics and Computing Science home: wietse@wzv.uucp | Eindhoven, The Netherlands
bobmon@iuvax.cs.indiana.edu (RAMontante) (04/24/89)
[ me ] >Is there a circumstance in which the comma operator is required, where >the compound statement cannot be broken into multiple statements? wietse@wzv.UUCP (Wietse Z. Venema) <268@wzv.UUCP> : - -"... in macros where a multistep computation has to be a single expression." - K&R second edition, page 63. I see that now, and thank you everybody. I find that when I originally posed the question I was mentally excluding macros from consideration, a curious lapse I admit. (BTW: I didn't mean to sound anti-comma.)
bink@aplcen.apl.jhu.edu (Ubben Greg) (04/24/89)
In article <2179@pur-phy> (Sho Kuwamoto) writes: >[...] >As for another example where you could use the comma operator usefully, >how about... > > for(i=0, p=head; p->next != NULL; i++, p=p->next) >or something. Right idea, but bad example. People too often cram expressions in the for(;;) that are not related to the loop control, just to avoid a couple of extra lines. I admit that I do it myself. In this case, the execution of the loop is totally dependent on the contents of the linked list. It would be more clearly written as: i = 0; for (p=head; p->next!=NULL; p=p->next) { /* I normally use "p" instead of "p->next!=NULL" */ /* We're skipping the last item here. */ i++; } It's especially hard to resist this when the for expression would otherwise be null. I would be tempted to hide the i=0 in its declaration and the i++ in an expression, but this is arguably also bad. Actually, I'm not all that firm on this opinion. Comments? -- Greg Ubben bink@aplcen.apl.jhu.edu
peter@ficc.uu.net (Peter da Silva) (04/24/89)
In article <1104@aplcen.apl.jhu.edu>, bink@aplcen.apl.jhu.edu (Ubben Greg) writes: > In article <2179@pur-phy> (Sho Kuwamoto) writes: > > for(i=0, p=head; p->next != NULL; i++, p=p->next) > People too often cram expressions in the for(;;) that are not related > to the loop control, just to avoid a couple of extra lines. I dispute that's the motivation in this case. But putting the i=0 and i++ in the loop you're providing extra information: that the variable 'i' is tightly bound to the loop, and may be serving as a manufactured loop index. The alternative: i = 0; for(p=head; p->next != NULL; p=p->next) { ... i++; } implies that 'i' might not be bound to the loop, and also means that you would have to special-case any 'continue' statement in the expression if it is so bound. if(gottagetouttahere) i++, continue; /* :-> */ (Yes, I know you can't do that). -- Peter da Silva, Xenix Support, Ferranti International Controls Corporation. Business: uunet.uu.net!ficc!peter, peter@ficc.uu.net, +1 713 274 5180. Personal: ...!texbell!sugar!peter, peter@sugar.hackercorp.com.
kremer@cs.odu.edu (Lloyd Kremer) (04/24/89)
In article <19913@iuvax.cs.indiana.edu> bobmon@iuvax.cs.indiana.edu (RAMontante) writes: >Is there a circumstance in which the comma operator is required, where >the compound statement cannot be broken into multiple statements? Perhaps not required, but convenient nevertheless. I often use it for loop tests using functions that "get" information but do not "return" the information they get. For example: extern double frexp(); double f[SIZE]; int i, exp; ... while(frexp(f[i++], &exp), exp < 10) statement; ... Another example would be: char c; while(read( ..., &c, 1), c != '\n') assuming EOF detection is not needed for this read() (horrible assumption, I know). -- Lloyd Kremer Brooks Financial Systems ...!uunet!xanth!brooks!lloyd Have terminal...will hack!
henry@utzoo.uucp (Henry Spencer) (04/25/89)
In article <28831@ucbvax.BERKELEY.EDU> jas@ernie.Berkeley.EDU (Jim Shankland) writes: >I still suggest that a C programmer who understands: > >(A) if (x->in_use) > { > x++; > y++; > } > >but who is mystified by: > >(B) if (x->in_use) > x++, y++; > >had best be investigating alternate career paths. This is very true. On the other hand, a C programmer who writes the latter should also be investigating alternate career paths, because he's clearly an amateur in a business that needs professionals. Anyone who says "any competent programmer ought to be able to understand that!" rather than "I should make my code as clear as possible!" is an amateur, and one with an ego problem at that. Readability is very much a matter of what you're used to. Like it or lump it, most C programmers are used to (A) and not (B). A programmer with a professional attitude will therefore use (A) to make his code as readable as possible, unless there is some special reason to do otherwise. To quote #8 from the Ten Commandments for C Programmers: Thou shalt make thy program's purpose and structure clear to thy fellow man by using [a familiar style], even if thou likest it not, for thy creativity is better used in solving problems than in creating beautiful new impediments to understanding. -- Mars in 1980s: USSR, 2 tries, | Henry Spencer at U of Toronto Zoology 2 failures; USA, 0 tries. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
les@chinet.chi.il.us (Leslie Mikesell) (04/25/89)
In article <19926@iuvax.cs.indiana.edu> bobmon@iuvax.cs.indiana.edu (RAMontante) writes: >->Is there a circumstance in which the comma operator is required, where >->the compound statement cannot be broken into multiple statements? >I said "required", not "useful". How about the more common: for (x=0, y=0; x <100 ; x++, y++) { stuff ... } Of course this could also be done other ways - the only thing "required" in a programming language is an assignment and a test-and-branch operator. The rest is merely "useful". Les Mikesell
ddb@ns.network.com (David Dyer-Bennet) (04/25/89)
In article <10098@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes:
:Ok, I picked a bad example. However, many macros need to accomplish
:more than one thing and cannot do so without the aid of some such
:trickery as
: ((expr1) & 0 | (expr2))
:which is more simply expressed as
: (expr1, expr2)
Which is an example of the weakness of the macro facility in C (one of the
most light-weight macro facilities I've ever had foisted on me). Without
taking a position on the general value of the comma operator -- the correct
solution to this one is to improve the macro facility, not provide a
way to kludge some (but not all) cases.
--
David Dyer-Bennet, ddb@terrabit.fidonet.org, or ddb@ns.network.com
or ddb@Lynx.MN.Org, ...{amdahl,hpda}!bungia!viper!ddb
or ...!{rutgers!dayton | amdahl!ems | uunet!rosevax}!umn-cs!ns!ddb
or Fidonet 1:282/341.0, (612) 721-8967 9600hst/2400/1200/300
jas@ernie.Berkeley.EDU (Jim Shankland) (04/25/89)
In article <1989Apr24.172219.817@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes: >On the other hand, a C programmer who [uses a comma operator to sequence >two closely related expression evaluations, instead of two statements] >should ... be investigating alternate career paths, because he's clearly >an amateur in a business that needs professionals. Anyone who says "any >competent programmer ought to be able to understand that!" rather than >"I should make my code as clear as possible!" is an amateur, and one with >an ego problem at that. Readability is very much a matter of what you're >used to. Like it or lump it, most C programmers are used to [the compound >statement] and not [the comma construct]. Sigh. Must have been lousy weather in Toronto that morning. We're agreed that a professional programmer should code as clearly and readably as possible, and that gratuitous cleverness is a bad thing. My original posting said so. What I consider self-evidently true, and you consider self-evidently false, is that the comma construct is sometimes at least as clear as the equivalent compound statement. Short of running code comprehension experiments on hundreds of bad C programmers, I don't see how we can resolve our difference of opinion. But at least I haven't questioned your professionalism. Now look what you've done. Made me grumpy. Not, on the whole, an easy thing to do. Jim Shankland jas@ernie.berkeley.edu "Blame it on the lies that killed us, blame it on the truth that ran us down"
friedl@vsi.COM (Stephen J. Friedl) (04/25/89)
In article <1989Apr24.172219.817@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) writes: > Anyone who says "any competent programmer ought to be able to understand > that!" rather than "I should make my code as clear as possible!" is an > amateur, and one with an ego problem at that. When writing software, always assume that the next person reading your code will be somebody much less qualified than you, and they will be required to fix a very hot bug with little time for study. You'll probably be right. Steve -- Stephen J. Friedl / V-Systems, Inc. / Santa Ana, CA / +1 714 545 6442 3B2-kind-of-guy / friedl@vsi.com / {attmail, uunet, etc}!vsi!friedl As long as Bush is in office, you'll never see Nancy Reagan in *my* .sig.
mat@mole-end.UUCP (Mark A Terribile) (04/25/89)
In article <1104@aplcen.apl.jhu.edu>, bink@aplcen.apl.jhu.edu (Ubben Greg) writes: > In article <2179@pur-phy> (Sho Kuwamoto) writes: > >As for another example where you could use the comma operator usefully, > >how about... > > for(i=0, p=head; p->next != NULL; i++, p=p->next) > Right idea, but bad example. People too often cram expressions in the > for(;;) that are not related to the loop control, just to avoid a couple of > extra lines. ... the execution of the loop is totally dependent on the > contents of the linked list. ... In this case, I respectfully disagree. Since the point of the loop is to establish a relationship between the number of items in the linked list and the value of i , and since the code that manipulates i is quite short, I prefer the ``compact'' form. Just be sure to write the null statement as something more than an unadorned semicolon. I like /* NULL */ ; and {} best myself. Even if there is something else that must be done each time around, I would prefer to put lockstep counting in the loop control; it reduces the likelyhood that someone who comes along later to do bodacious things to the other code will mess up this important but hard-to-see-for-its-small-size counting code. Oh, and I *definately* *would* *not* put the initialization of i in the declaration unless it were a nested local declaration whose scope began right before the for(;;) and expired right after the for(;;). Even then I'd have some doubts. The initialization to zero is part of establishing that relationship between the cardinality of the linked list (if I may express the thing that way) and the value of i . -- (This man's opinions are his own.) From mole-end Mark Terribile
toddpw@tybalt.caltech.edu (Todd P. Whitesel) (04/25/89)
a side note about this comma brouhaha: on a convex x-mp running convex unix, a code fragment such as foo (parm1,parm2), foo2 (parm1,parm2); is illegal and gets you screens full of syntax errors from both lint and cc. hmmm..... toddpw @ caltech.bitnet toddpw @ romeo.caltech.edu
crewman@bucsb.UUCP (JJS) (04/26/89)
In article <1989Apr24.172219.817@utzoo.uucp> (Henry Spencer) writes: > >On the other hand, a C programmer who [uses a comma operator to sequence >two closely related expression evaluations, instead of two statements] >should ... be investigating alternate career paths, because he's clearly >an amateur in a business that needs professionals. Anyone who says "any >competent programmer ought to be able to understand that!" rather than >"I should make my code as clear as possible!" is an amateur, and one with >an ego problem at that. Readability is very much a matter of what you're >used to. Like it or lump it, most C programmers are used to [the compound >statement] and not [the comma construct]. > I believe that should read, 'most *Pascal* programmers are used to the compound statement and not the comma construct'. This is just my opinion, and one with which many people differ, but why are C programmers always advised not to use the unique features of C? So far, I've been advised against: -- using the comma construct -- using the (a ? b : c) expression -- using an assignment as a function -- using "if (a)" instead of "if (a != 0)" -- using += -= *= /= |= &= ^= -- using << >> <<= >>= -- using complex pointer-integer expressions -- generally complex expressions: map |= (line[k++] = string[j++]); -- writing compact source code etc. I've also been advised to go out of my way to make my C programs look like programs written in another language: #define begin { #define end } #define then /* if (a == 1) then return; */ #define when break; case /* when 'a': foo(); when 'b': bar() */ #define otherwise break; default: /* otherwise baz(); */ etc. Getting back to the poster of the above article, why is the person who likes the comma construct an amateur? Is it because s/he likes a unique feature of C? Or is it really because the above "professional" would get confused reading such code? In a business which so sorely "needs professionals", why are we bending over backwards to make our programs easier to read for ama- teurs? C is designed to be a low-level language. It's advantage over machine language and even higher-level languages is its power derived from its simplicity and compactness. It is in this way an elegant language; as C programmers, we have the tools to make powerful programs compact. Yet we are constantly advised to throw away these tools. I believe that that is VERY unprofessional. I repeat: this is just my opinion so mail flames to me. -- JJS
diamond@diamond.csl.sony.junet (Norman Diamond) (04/26/89)
In article <19926@iuvax.cs.indiana.edu> bobmon@iuvax.cs.indiana.edu (RAMontante) writes: >>>>Is there a circumstance in which the comma operator is required, where >>>>the compound statement cannot be broken into multiple statements? >>> >>I said "required", not "useful". In article <8284@chinet.chi.il.us> les@chinet.chi.il.us (Leslie Mikesell) writes: >How about the more common: > >for (x=0, y=0; x <100 ; x++, y++) { > stuff ... >} > >Of course this could also be done other ways - the only thing "required" >in a programming language is an assignment and a test-and-branch operator. >The rest is merely "useful". Why two operators? The sole required operator is "subtract, assign, and branch if negative." Norman Diamond, Sony Computer Science Lab (diamond%csl.sony.jp@relay.cs.net) The above opinions are my own. | Why are programmers criticized for If they're also your opinions, | re-inventing the wheel, when car you're infringing my copyright. | manufacturers are praised for it?
henry@utzoo.uucp (Henry Spencer) (04/27/89)
In article <28890@ucbvax.BERKELEY.EDU> jas@ernie.Berkeley.EDU.UUCP (Jim Shankland) writes: >Sigh. Must have been lousy weather in Toronto that morning. No, actually, the Toronto weather's been fine. >We're agreed that a professional programmer should code as clearly >and readably as possible, and that gratuitous cleverness is a bad >thing. My original posting said so. What I consider self-evidently >true, and you consider self-evidently false, is that the comma >construct is sometimes at least as clear as the equivalent compound >statement... As my original posting said, it is a well-established fact, backed by various experiments on things like reading rates, that familiar styles are easier to read. This particular comma construct is uncommon and hence likely to be unfamiliar. QED. There are always unusual cases where the usual style is, for some special reason, less clear than some variant. But these are unusual cases, and should not be taken to indicate acceptable variation in normal code. -- Mars in 1980s: USSR, 2 tries, | Henry Spencer at U of Toronto Zoology 2 failures; USA, 0 tries. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
gwyn@smoke.BRL.MIL (Doug Gwyn) (04/27/89)
In article <1989Apr26.214622.10697@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes: >As my original posting said, it is a well-established fact, backed by >various experiments on things like reading rates, that familiar styles >are easier to read. This particular comma construct is uncommon and >hence likely to be unfamiliar. QED. Oh, come on, Henry, what is "common" or "familiar" depends very much on one's experience. There are many common cases of truly horrible coding style, and most of us are familiar with examples of it. That in itself does not make it easier to read, desirable, or anything else along those lines. The best one can say is that familiarity is one positive factor in code readability, but there are many others too. Clear logical structure is probably more important. While I don't recommend unbridled use of comma operators in place of semicolons, neither would I call usage such as while ( norm( x, y, z ) < distance ) ++x, ++y, ++z; "unreadable". It seems to me that it would be perfectly readable to anyone who should be attempting to deal with C code at all. It may even be preferable to adding the extra punctuation that you recommend.
bagpiper@oxy.edu (Michael Paul Hunter) (05/02/89)
In article <28831@ucbvax.BERKELEY.EDU> jas@ernie.Berkeley.EDU (Jim Shankland) writes: >Granted, everyone should write code that is easily understandable by >others. Granted, also, that the way to do that depends on idioms in >common use in a particular language: constructs that are common usage >in, e.g., LISP, may be obscure in C. Granted, finally, that it is quite >possible to write obscure C code by using the comma operator (and in >countless other ways). With a finite language (finite number of symbols), a finite number of states, and a finite length program, I believe that you are only going to get a countable (finite) number of ways to write obscure code... :) maybe large...but finite! mike