shekita@crystal.UUCP (06/21/85)
I am currently modifying C code, written by someone else, that is incredibly terse. It's paramount that the code be fast, so I presume the code is terse for speed. I'm now curious about a few things: 1) Is the "var = (bool expr) ? : expr1 : expr2" construct faster than just a good old if statement? 2) Are for loops faster than while loops? 3) Is there really much to be gained by using assignment within a boolean expression, for example, is if ((fp = fopen("foo", "r") == NULL) { ... } really that much faster than fp = fopen("foo", "r"); if (fp == NULL) { ... } 4) Are tests for zero more efficently written as if (var) { ... } rather than as if (var != 0) { ... }
chris@umcp-cs.UUCP (Chris Torek) (06/22/85)
All of these depend on your compiler. I'm going to answer them for 4BSD Vax PCC. > 1) Is the "var = (bool expr) ? : expr1 : expr2" construct faster > than just a good old if statement? Depends. PCC generates moves into r0 for expr1 and expr2, followed by a move from r0 to var. If var is already a register, this is clearly slower. If it's a complex pointer dereference, it could be faster. > 2) Are for loops faster than while loops? No. > 3) Is there really much to be gained by using assignment within > a boolean expression, for example, is > > if ((fp = fopen("foo", "r") == NULL) { > > really that much faster than > > fp = fopen("foo", "r"); > if (fp == NULL) { Again, depends: if "fp" is not a register, the assignment+test is faster, since you end up branching after the assignment from r0 to "fp". If it is a register, it comes out the same. (At least after optimization, usually). The first form is never slower, anyway. > 4) Are tests for zero more efficently written as > > if (var) { > > rather than as > > if (var != 0) { No. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251) UUCP: seismo!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@maryland
jjd@wlcrjs.UUCP (Joe Durnavich) (06/25/85)
>> 3) Is there really much to be gained by using assignment within >> a boolean expression, for example, is >> >> if ((fp = fopen("foo", "r") == NULL) { >> >> really that much faster than >> >> fp = fopen("foo", "r"); >> if (fp == NULL) { > >Again, depends: if "fp" is not a register, the assignment+test is faster, >since you end up branching after the assignment from r0 to "fp". If it >is a register, it comes out the same. (At least after optimization, usually). >The first form is never slower, anyway. This example bothers me. I'm not sure what all makes up the fopen subroutine, but the addition or subtraction of one measely assignment statement *has* to be negligible when compared to what goes on in fopen. Even if that code is in the innermost of inner loops, the "optimization" will still be unnoticable. I know it's just an example of an assignment within a boolean expression, but I see a *lot* of programs with that same code. Are we really gaining anything, or is it merely psychological? Joe Durnavich ihnp4!wlcrjs!jjd No part of this message may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, without the permission of the author.
minow@decvax.UUCP (Martin Minow) (06/26/85)
The question was asked whether the common C idiom if ((fp = fopen("foo.bar", "r")) == NULL) { ... really is more efficient than fp = fopen("foo.bar", "r"); if (fp == NULL) { ... In response, Joe Durnavich makes the good point that the saving of one measly move instruction (which a good compiler would optimize out anyway) isn't worth the effort. In response, I would again point out that this is a C idiom -- one of the habits a programmer picks up for better or worse. In defense, I would note that writing this as a single statement ties (visually) the if condition closer to the fopen() result that is being tested than would be the case were one to write two statements. Martin Minow decvax!minow
chris@umcp-cs.UUCP (Chris Torek) (06/27/85)
> This example [ if ((fp = fopen(...)) == NULL) vs fp = fopen(...); if (fp == NULL) ] > bothers me. I'm not sure what all makes up the fopen subroutine, > but the addition or subtraction of one measly assignment statement > *has* to be negligible when compared to what goes on in fopen. > Even if that code is in the innermost of inner loops, the "optimization" > will still be unnoticable. I know it's just an example of an > assignment within a boolean expression, but I see a *lot* of programs > with that same code. Are we really gaining anything, or is it > merely psychological? Heck, 500 nanoseconds is significant, isn't it? :-) Besides, you can save four bytes per test. I'll bet it makes a disk block or two of difference. And we all need all the space we can get, right? :-) Seriously, the difference in the fopen call is pretty small, but the difference in something like for (...) for (...) { if ((j = (k >> 2) - m) == 0) k++; } can be important. Once you get into the habit of testing the results of an assignment, it doesn't even look funny anymore. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251) UUCP: seismo!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@maryland
mhs@enmasse.UUCP (Mike Schloss) (06/27/85)
> I am currently modifying C code, written by someone else, > that is incredibly terse. It's paramount that the code > be fast, so I presume the code is terse for speed. I'm > now curious about a few things: > > . > . > . Sorry but it all depends on your particular compiler implementation and the machine you are running on. There are two ways to find the answers to your questions. One is to write a simple test program and use the '-S' flag of the compiler. This will produce assembly code that you can examine and see what intructions are being generated for any particular expression. If you dont want to get your hands dirty with assembler then write your test program to run a couple 100k times though each expression and time it.
brooks@lll-crg.ARPA (Eugene D. Brooks III) (06/28/85)
> >> if ((fp = fopen("foo", "r") == NULL) { > This example bothers me. I'm not sure what all makes up the > fopen subroutine, but the addition or subtraction of one measely > assignment statement *has* to be negligible when compared to what > goes on in fopen. Even if that code is in the innermost of inner > loops, the "optimization" will still be unnoticable. I know > it's just an example of an assignment within a boolean expression, > but I see a *lot* of programs with that same code. Are we really > gaining anything, or is it merely psychological? Its its not for the sake of exectution efficiency. You see it a lot for the sake of statement efficiency. Its the efficient and STANDARD way of saying it. Any experienced C programmer recognizes this code automatically and produces it without thinking. You have problems with it because you are not an experienced C programmer yet. You of course need to include the missint paren :-)
bright@dataio.UUCP (Walter Bright) (06/28/85)
In article <474@crystal.UUCP> shekita@crystal.UUCP writes: >I am currently modifying C code, written by someone else, >that is incredibly terse. It's paramount that the code >be fast, so I presume the code is terse for speed. For every case you mentioned, I can think of different compilers where one case is faster in one compiler and the other case is faster for the other compiler. The only way to tell for sure for your compiler is to examine the assembly code output.
zarth@drutx.UUCP (CovartDL) (06/28/85)
I have noticed lately that if I have the following: foo() { char c; if((c = getchar()) != '\n') { /* more code here */ } } and I do not use 'c' any where else lint complains. I get the message c set but no used in function foo I tried reverseing the test as below thinking c would have to appear on the right side of at least one test but, I get the same error. foo() { char c; if('\n' != (c = getchar())) { /* more code here */ } } Is it simply the use of the compound statement structure that causes this?? Thanks in advance for the solution. - Zarth Arn
ark@alice.UUCP (Andrew Koenig) (06/29/85)
> I have noticed lately that if I have the following: > foo() > { > char c; > > if((c = getchar()) != '\n') { > /* more code here */ > } > } > > and I do not use 'c' any where else lint complains. I get the message > > c set but no used in function foo Ummm... isn't lint right? Why couldn't you just write: if (getchar() != '\n') { ...
mash@mips.UUCP (John Mashey) (06/29/85)
> > >> if ((fp = fopen("foo", "r") == NULL) { > > Its its not for the sake of exectution efficiency. You see it > a lot for the sake of statement efficiency. ... It is also useful for human efficiency, once you become accustomed to the idiom. Code must be read and understood by humans; less (signifcant, not {}, (), etc) tokens are generally faster, within reasonable limits. A similar example is OP= operators; i.e., x = x + 3 requires slightly longer to read than x += 3, if only because you don't have tyo check that the variables on the right and left are the same. Trivial in this case, but less so when it's long_identifier1 += 3 instead of long_identifier1 += long_identifier1 + 3; No one would claim this is a big effect, but every little bit helps, especially when it even makes life easier for the compiler. -- -john mashey UUCP: {decvax,ucbvax,ihnp4}!decwrl!mips!mash DDD: 415-960-1200 USPS: MIPS Computer Systems, 1330 Charleston Rd, Mtn View, CA 94043
henry@utzoo.UUCP (Henry Spencer) (06/30/85)
> Seriously, the difference in the fopen call is pretty small, but > the difference in something like > > for (...) > for (...) { > if ((j = (k >> 2) - m) == 0) > k++; > } > > can be important. Once you get into the habit of testing the results > of an assignment, it doesn't even look funny anymore. Retch. To quote the "Indian Hill C Style" paper: For example, the code: .DS a = b + c; d = a + r; .DE should not be replaced by .DS d = (a = b + c) + r; .DE even though the latter may save one cycle. Note that in the long run the time difference between the two will decrease as the optimizer gains maturity, while the difference in ease of maintenance will increase as the human memory of what's going on in the latter piece of code begins to fade... -- Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,linus,decvax}!utzoo!henry
henry@utzoo.UUCP (Henry Spencer) (06/30/85)
> ... Any experienced C programmer recognizes this code > automatically and produces it without thinking. You have problems with > it because you are not an experienced C programmer yet. Rubbish. "Any experienced programmer should be able to understand that" really means "we know it's hard to read, but...". The idea is to make life as easy as possible for the poor guy who has to maintain the stuff next. Note "as easy as possible", as opposed to "not quite impossible". I've been programming in C for over a decade, by the way. -- "Maturity means doing what's right, not just what's easy." Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,linus,decvax}!utzoo!henry
quiroz@rochester.UUCP (Cesar Quiroz) (07/01/85)
From article <3136@drutx.UUCP> (version B 2.10.2 9/18/84; site rochester.UUCP version B 2.10.1 (Denver Mods 7/26/84) 6/24/83; site drutx.UUCP rochester!seismo!harvard!think!mit-eddie!genrad!decvax!harpo!whuxlm!whuxl!houxm!ihnp4!drutx!zarth zarth@drutx.UUCP (CovartDL)): >I have noticed lately that if I have the following: > > foo() > { > char c; > > if((c = getchar()) != '\n') { > /* more code here */ > } > } > >and I do not use 'c' any where else lint complains. I get the message > > c set but no used in function foo > . . . > > - Zarth Arn Seems like a very desirable behavior in the part of Lint. Either you really need the value of c someplace else (and then your program contains a bug) or it could be easily simplified as: foo() { /* NOT NEEDED: char c; */ if(((char) getchar()) != '\n') { /* more code here */ } } Or something similar that doesn't keep the value of getchar() in a useless variable. At any rate, be sure you really don't need it! Cesar
chris@umcp-cs.UUCP (Chris Torek) (07/02/85)
There is actually a difference between char c; while ((c = getchar()) != '\n') and while (getchar() != '\n') The latter expression compares the return value of getchar() (an int) with '\n' (another int). The former compares the value of the assignment "c = getchar()" (a char) with an int. Lint is arguably correct in complaining, as "c" itself is not actually used in the comparison, but it does have an effect. By the way, the former section of code is technically incorrect: getchar returns an int, since EOF is supposed to be something that is not valid as a char. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251) UUCP: seismo!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@maryland
chris@umcp-cs.UUCP (Chris Torek) (07/02/85)
>>[...] it all depends on your particular compiler >>implementation [...] use the '-S' flag of the compiler >>[to] produce assembly code that you can examine [...]. >Unfortunately, this option is not likely to show you the >optimized code you would get from running the compiler with >the -O flag. To really see what's being generated, compile >it, and then look at the object file with something like >foo,24?ai >in adb. That's not necessary; -O and -S work just fine together, at least under 4BSD (including Sun 4.2). -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251) UUCP: seismo!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@maryland
mhs@enmasse.UUCP (Mike Schloss) (07/02/85)
> I have noticed lately that if I have the following: > > foo() > { > char c; > > if((c = getchar()) != '\n') { > /* more code here */ > } > } > > and I do not use 'c' any where else lint complains. I get the message > > c set but no used in function foo > Whats the problem? Lint is telling you that your loop keeps assigning a value to c and never ever using it. (Is c in WOM :-) You could get away with something like this: foo() { if (getchar() != '\n') { /* more code here */ } }
guy@sun.uucp (Guy Harris) (07/02/85)
> Unfortunately, this option (-S - ed) is not likely to show you the > optimized code you would get from running the compiler with > the -O flag. No, but cc -S -O amor_y_cohetes.c will run the generated assembly code through the peephole optimizer, so the resulting ".s" file will show the optimized code. Guy Harris
brooks@lll-crg.ARPA (Eugene D. Brooks III) (07/02/85)
> > ... Any experienced C programmer recognizes this code > > automatically and produces it without thinking. You have problems with > > it because you are not an experienced C programmer yet. > > Rubbish. "Any experienced programmer should be able to understand that" > really means "we know it's hard to read, but...". The idea is to make No!, it does not mean that. It means that the novice who has the complaint about not being able to understand things like if((fptr = fopen(filename, "r")) == NULL) { printf(stderr, ".....", .....); exit(1); } Does not yet clearly understand that in C the expression (a = b) has a value, which is whats on the RHS of the =, that can be conviently tested! The same goes for the novice who does not understand why lint complains that c is not used in foo() { int c; if((c = getchar()) != '\n') { SOME CODE } }
fletcher@im4u.UUCP (07/03/85)
In article <2367@sun.uucp> jfarrell@sun.UUCP (Jerry Farrell) writes: >> >>One is to write a simple test program and use the '-S' >>flag of the compiler. > >Unfortunately, this option is not likely to show you the >optimized code you would get from running the compiler with >the -O flag. To really see what's being generated, compile >it, and then look at the object file with something like >foo,24?ai >in adb. Adb to see if your code is optimized? Now that's real masochism. Just do 'cc -O -S foo.c'. This fails if you do 'cc -OS foo.c', which is probably what you were refering to. This is with 4.2's compiler. -- Fletcher Mattox, fletcher@ut-sally.ARPA, {ihnp4,seismo,ctvax}!ut-sally!fletcher
chris@umcp-cs.UUCP (Chris Torek) (07/03/85)
Let's not start this again... the value of an assignment is the LHS, not the RHS. Ref. ANSI draft X3J11, sec. C.3.16, Assignment Operators: Constraints: Each assignment operator must have an lvalue as its left operand. Semantics An assignment operator stores a value in the object specified by the lvalue. An assignment expression has the type of the left operand and the value of the left operand after the assignment. The storage must take place before the value of the assignment is used. The order of evaluation of the right operand and the lvalue is unspecified. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251) UUCP: seismo!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@maryland
arnold@gatech.CSNET (Arnold Robbins) (07/03/85)
> >One is to write a simple test program and use the '-S' > >flag of the compiler. This will produce assembly code > >that you can examine and see what intructions are being > >generated for any particular expression. > > Unfortunately, this option is not likely to show you the > optimized code you would get from running the compiler with > the -O flag. To really see what's being generated, compile > it, and then look at the object file with something like > foo,24?ai > in adb. Sorry, but 'cc' is smart enough to run the optimizer on the assembler if you give it 'cc -S -O foo.c'. foo.s will be optimized assembly. -- Arnold Robbins CSNET: arnold@gatech ARPA: arnold%gatech.csnet@csnet-relay.arpa UUCP: { akgua, allegra, hplabs, ihnp4, seismo, ut-sally }!gatech!arnold Hello. You have reached the Coalition to Eliminate Answering Machines. Unfortunately, no one can come to the phone right now....
roy@phri.UUCP (Roy Smith) (07/04/85)
> > > ... Any experienced C programmer recognizes this code > > if((fptr = fopen(filename, "r")) == NULL) Somebody mentioned economy of expression being a good thing; agreed. In this particular case the idiom is so well ingrained that I don't think twice about it. In fact, doing it any other way would require more thought. Saving a line or two of source makes it that much more likely that the entire 'phrase' will fit on your screen at one time, enhancing comprehension. About the only time I would split the assignment and the test is when the line would run off the edge of the screen otherwise. -- allegra!phri!roy (Roy Smith) System Administrator, Public Health Research Institute
henry@utzoo.UUCP (Henry Spencer) (07/04/85)
> > Rubbish. "Any experienced programmer should be able to understand that" > > really means "we know it's hard to read, but...". The idea is to make > > No!, it does not mean that. It means that the novice who has the complaint > about not being able to understand things like [assignment inside if] > does not yet clearly understand that in C the expression (a = b) has a value, > which is whats on the RHS of the =, that can be conviently tested! It is entirely possible to understand the semantics of the code fully and still consider it unnecessarily obscure and hard to read. The mark of a good programmer is that his code is *easy* to read, not just *possible* to read. Using every obfuscatory feature of the language, perhaps in the (oft-mistaken) belief that it improves efficiency, and then pleading that "any experienced programmer should be able to understand that" is the mark of someone who doesn't understand what this business is about. "To be clear is professional; not to be clear is unprofessional." -- Sir Ernest Gowers -- Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,linus,decvax}!utzoo!henry
jss@sftri.UUCP (J.S.Schwarz) (07/06/85)
> > Sorry, but 'cc' is smart enough to run the optimizer on the assembler > if you give it 'cc -S -O foo.c'. foo.s will be optimized assembly. > -- AT&T compilers these days all come with a tool, call "dis", for disassembler. that look at object files and tell you exactly what instructions are in them. This is neccessary because it is sometimes not possible to look at a .s and tell exactly what instructions the assembler will produce. For example an assembler might replace some long forms of jumps by short forms. Jerry Schwarz attunix!jss AT&T-IS Summit, N.J.
jfarrell@sun.uucp (Jerry Farrell) (07/07/85)
In article <420@enmasse.UUCP> mhs@enmasse.UUCP (Mike Schloss) writes: >> I am currently modifying C code, written by someone else, >> that is incredibly terse. It's paramount that the code >> be fast, so I presume the code is terse for speed. I'm >> now curious about a few things: > >Sorry but it all depends on your particular compiler >implementation and the machine you are running on. >There are two ways to find the answers to your questions. >One is to write a simple test program and use the '-S' >flag of the compiler. This will produce assembly code >that you can examine and see what intructions are being >generated for any particular expression. Unfortunately, this option is not likely to show you the optimized code you would get from running the compiler with the -O flag. To really see what's being generated, compile it, and then look at the object file with something like foo,24?ai in adb.
guy@sun.uucp (Guy Harris) (07/08/85)
> AT&T compilers these days all come with a tool, call "dis", for > disassembler. that look at object files and tell you exactly what > instructions are in them. Well, some AT&T compilers, anyway - the S5R2 documentation describes DIS(1) as "3B20 only". > This is neccessary because it is sometimes not possible to look at a > .s and tell exactly what instructions the assembler will produce. For > example an assembler might replace some long forms of jumps by short > forms. The PDP-11, VAX, and 68000 assemblers I've seen don't replace long jumps with short jumps; they replace a "generic" jump with a short or long jump. Then again, for the purposes of inspecting generated code to see "how good it is", this shouldn't make much of a difference; looking at the ".s" files should suffice. The disassembler may be useful for 3Bs; I believe they have a "generic" assembler language which translates into 3B20 or WE32000-series binary code. Guy Harris
DHowell.ES@Xerox.ARPA (07/09/85)
> Somebody mentioned economy of expression being a good thing; >agreed. In this particular case the idiom is so well ingrained that I >don't think twice about it. In fact, doing it any other way would >require more thought. Don't think too much, it could be dangerous :-) But really, if you must keep up the high priesthood of programming, then go ahead and use your idioms. I personally think that programming is a tool for all and not a science for a few. Idioms which are believed to be more efficient (sometimes mistakenly) should be given up in favor of constructs which are common to most programming languages. I know that things can't be done the same in all programming languages, but what can be, should. It is simply a matter of making it understandable to all who are involved with a project, programmers and non-programmers alike. Dan
jon@cit-vax.ARPA (Jonathan P. Leech) (07/10/85)
> From: DHowell.ES@XEROX.ARPA > ... > Idioms which are believed to be more > efficient (sometimes mistakenly) should be given up in favor of > constructs which are common to most programming languages. I know that > things can't be done the same in all programming languages, but what can > be, should. It is simply a matter of making it understandable to all > who are involved with a project, programmers and non-programmers alike. > > Dan Would you then recommend that we eliminate pointers and structures from our code? BASIC, FORTRAN and APL don't have them. I will place myself out on a limb by stating that, in my experience, non-programmers don't look at code and care that is WORKS, not how elegant it is. I would hate to program in a common subset of all languages. I far prefer to let the comments describe the algorithm and the implementation be hand-optimized and obscure, if that makes it run significantly faster. And sometimes it does. I've been doing a lot of ray tracing recently, and at >8 hours frame, I CARE about efficiency! Jon Leech jon@cit-vax-arpa __@/
bright@dataio.UUCP (Walter Bright) (07/10/85)
In article <147@mips.UUCP> mash@mips.UUCP (John Mashey) writes: >It is also useful for human efficiency, once you become accustomed to the >idiom. Code must be read and understood by humans; less (signifcant, not >{}, (), etc) tokens are generally faster, within reasonable limits. >A similar example is OP= operators; i.e., x = x + 3 requires slightly >longer to read than x += 3, if only because you don't have tyo check that >the variables on the right and left are the same. Trivial in this case, >but less so when it's long_identifier1 += 3 instead of >long_identifier1 += long_identifier1 + 3; Also, when I program I think "ok, now add 3 to x". I do not think "ok, now take x, add 3 to it and stuff it back into x". I like the op= operators because they allow me to program the way I think.
bc@cyb-eng.UUCP (Bill Crews) (07/10/85)
>>> Rubbish. "Any experienced programmer should be able to understand that" >>> really means "we know it's hard to read, but...". The idea is to make >> >> No!, it does not mean that... > It is entirely possible to understand the semantics of the code fully and > still consider it unnecessarily obscure and hard to read. The mark of a > good programmer is that his code is *easy* to read, not just *possible* to > read. Using every obfuscatory feature of the language, perhaps in the > (oft-mistaken) belief that it improves efficiency, and then pleading that > "any experienced programmer should be able to understand that" is the mark > of someone who doesn't understand what this business is about. Henry, I have read a number of your postings about the "professionalism" of code readability, and while I generally applaud and agree with you, there is nevertheless a feeling I get whenever I read such an article that you apparently believe that that which is most easily readable by one programmer is also most easily read by another programmer. I heartily disagree with this notion (if it IS your notion). My most heavily-used language before learning C was PL/I, which looks much like C *structurally*, BUT without the side effects such as imbedded assignments that C has. Perhaps that is the reason I tend to agree with your statements somewhat. However, as I get more used to reading C of various flavors, such constructs HAVE gotten easier for me to read, and they may someday become easier for me than PL/I-style, if for no other reason than familiarity. I tend to target a programmer with a thorough knowledge of the language, but I try to refrain from forcing that programmer to exercise his powers of lexical analysis without warrant. I do NOT assume that that programmer has read a lot of AT&T code (a dubious distinction) or a lot of anybody else's code, as you seemed to in a posting not long ago on the topic of indentation style. I gathered then that your feeling was that anyone who deviates from K&R (and, I suppose, AT&T kernel default) style was being UNPROFESSIONAL by doing so REGARDLESS of how readable one judged this style to be to his targeted reading population. Obviously, I disagree with this, perhaps because I have programmed in C for years and have never done Unix kernel work. Without stating where I put my braces (I don't want to start any more religious wars), I will state that they differ from K&R style, and that they are positioned such that, in MY estimation, MOST human beings (not just kernel hackers) that read it can adapt to it based upon NO assumption of their C reading experience. And, yes, I suppose I recommend this to others. -- / \ Bill Crews ( bc ) Cyb Systems, Inc \__/ Austin, Texas [ gatech | ihnp4 | nbires | seismo | ucb-vax ] ! ut-sally ! cyb-eng ! bc
roy@phri.UUCP (Roy Smith) (07/11/85)
I said: > > [...] the idiom is so well ingrained that I don't think twice about it. DHowell.ES@Xerox.ARPA (Dan) responded: > Don't think too much, it could be dangerous :-) I try not to, it's too much work. :-) > Idioms which are believed to be more efficient (sometimes mistakenly) > should be given up in favor of constructs which are common to most > programming languages. [...] making it understandable to all who are > involved with a project I can't argue with that. I use "if ((fd = fopen(...)) == NULL)" not because it runs faster but because I think it makes the program easier to understand. We clearly have the same goal; making like easier on people who have to read our code later on, even if it costs a bit in execution. We just disagree on how to reach that goal. I also am one of those people who sneer at complex code. It just so happens, however, that the 2 particular idioms I have seen attacked recently (testing and assigning the value of a function at the same time, and using "i++" instead of "i = i + 1") are among the few that are on my "so ingrained that I don't think twice" list. Obviously you have a different definition for "complex idiom" than I do. Fair enough. I do disagree with your point about using only those features of C which are in common with other programming languages. I'm not about to give up structures and pointers just because FORTRAN doesn't have them. Nor am I going to do without the conditional, boolean, or various assignment operators. They're part of C so why shouldn't I use (not abuse) them? Stuff like "i += xtab[foo++->bar[flag?baz1:baz2]]--" is wantonly confusing; "i += foo->bar" is not. More important than what idioms you use is how (or if!) you comment the code. How many times have you tried to read 10 pages of dense code without any useful comments? Isn't commenting something they teach in "Intro to Computers and Programming 101"? So why don't people do it? I can deal with figuring out the gritty details of what a certain idiom means as long as the author gives me a clue as to what is going on. It would be nice if the code was *both* simple and commented. Force to choice one or the other, I'll take the comments any day. With a roadmap, I can usually find my way through the convoluted code -- it's not so easy the other way around. -- allegra!phri!roy (Roy Smith) System Administrator, Public Health Research Institute
guy@sun.uucp (Guy Harris) (07/12/85)
> I personally think that programming is a tool for all and not a science > for a few. It is simply a matter of making it understandable to all > who are involved with a project, programmers and non-programmers alike. How inclusive is your "all"? It's silly to expect everybody to understand all that's involved in programming. Should all automobiles be constructed using technology understandable by "all"? No. Most people don't have the background to understand how a catalytic converter works, or example. It's sufficient to construct automobiles so they're *usable* by all. The same is true of software. Software should be usable by the widest possible collection of people, but the person constructing the program shouldn't care whether the person using it could understand the code when presented to them. The C programming language is a tool. A person using a tool is assumed to have some minimum amount of knowledge about the tool they're using. I think the "if ((stream = fopen(filename, mode)) == NULL)" idiom, or the "a++" idiom, is in that minimum. Sneaky code like "a = (b = c) + d" is not. Guy Harris
gwyn@BRL.ARPA (VLD/VMB) (07/14/85)
I have to disagree with your view that "programming is a tool for all and not a science for a few". Most of the problems I have encountered with software have been the direct result of it being produced by amateurs who were apparently both unaware of the science and unfamiliar with the proper usage of the tools. C is meant for experienced, professional programmers; and even those are expected to learn about the language before dealing with it. It makes no sense to argue that all code should be readable by those unfamiliar with the language; would you prohibit the use of classes in C++, data structures and pointers in C, etc. simply because people whose experience is limited to a BASIC primer don't understand them?
dmh@dicomed.UUCP (Dave Hollander) (07/15/85)
This is turning out to be quite a strange discussion. First, my dictionary defines "idiom" as an accepted phrase or expression... the i++ construct is not only accepted by most C programmers but also by the compiler. Second, why would anyone want to chew up white space in an expression and give the mind more tokens to think about? The rest of the definition involes "having a meaning *different* than the literal". I can not think of a more literal definition than K&R did. The whole poin
jerry@oliveb.UUCP (Jerry Aguirre) (07/17/85)
> But really, if you must keep up the high priesthood of programming, then > go ahead > and use your idioms. I personally think that programming is a tool for > all and not a science for a few. Idioms which are believed to be more Right :-) And electrictions should no longer use all those technical words like amps and guage. They should just talk about big wires and little wires :-) Electronic schematics should get rid of all those hard to understand symbols and draw pictures of what each component really looks like :-) Doctors should use simple terminology like "tummy ache" when writting on the patients chart :-) An physisists should just competely stop talking about all those teeny-tiny things that can't be seen and therefore don't exist :-) All those priests should stop talking in their secret languages and talk plain english so that the general public can understand them :-) Jerry Aguirre @ Olivetti ATC {hplabs|fortune|idi|ihnp4|tolerant|allegra|tymix}!oliveb!jerry
oz@yetti.UUCP (Ozan Yigit) (07/17/85)
In article <11554@brl-tgr.ARPA> gwyn@BRL.ARPA (VLD/VMB) writes: >I have to disagree with your view that "programming is a tool for all >and not a science for a few". Most of the problems I have encountered >with software have been the direct result of it being produced by >amateurs who were apparently both unaware of the science and >unfamiliar with the proper usage of the tools. > Umph!!! I have been involved in decus for a long time, and have gone through *all* tapes since 1978. These tapes contain stuff from Universities (where the Computer Science is tought) to many commercial organizations. I could safely say that there is *no* one-to-one correspondance between so-called professionals and the awareness of the science of programming. You could say that I have encountered more trash written (in macro, fortran, basic, C, pascal) by professionals (?) than otherwise. As someone said eons ago: An educated fool is often more foolish than an uneducated one. >C is meant for experienced, professional programmers.. Is that right ?? It seems the highschool students (Who perhaps started out with basic) write just as good C code as "professionals", as Lincoln-Sudbury stuff in one of the usenix tapes prove. By the way, what does "professional" mean ?? Someone making a living thru programming ??? I suppose "experienced" means someone who has programmed in fortran, basic, cobol and apl ??? (Perhaps this does not count - experienced means someone who has programmed in C and C alone, the god-given tool of higher learning, professionality and superhackerdom !!) >[it] makes no sense to argue that all code should be readable by those >unfamiliar with the language; would you prohibit the use of classes >in C++, data structures and pointers in C, etc. simply because people >whose experience is limited to a BASIC primer don't understand them? > The idea is to make the program as *clear* as possible, or to put it in Einstein's words: "As simple as possible, but not simpler". As the obfuscated C contest proves, one can write C code that looks like Apl, almost unreadable, yet it works. Than you spend about three times as much time as it took to write it, to untangle it, perhaps without success. What "seems" efficient may not be so, and thus, unreadability is a high price to pay for it: "Premature optimization is root of all evil" [Kernighan and Plauger, The elements of Programming Style, 1978] [fill in other classic quotations from Knuth, Jon Bentley etc. here] -- Oz [all wizardesque side effects are totaly unintentional, unless stated otherwise..] Usenet: [decvax | allegra | linus | ihnp4] !utzoo!yetti!oz Bitnet: oz@ [yuleo | yuyetti] ------------- Support GNU. Consider the 3-muskateers' motto: ONE FOR ALL - ALL FOR ONE
henry@utzoo.UUCP (Henry Spencer) (07/17/85)
> ... I could safely > say that there is *no* one-to-one correspondance between > so-called professionals and the awareness of the science of > programming. You could say that I have encountered more > trash written (in macro, fortran, basic, C, pascal) by > professionals (?) than otherwise... > > ... It seems the highschool students (Who perhaps > started out with basic) write just as good C code as > "professionals", as Lincoln-Sudbury stuff in one of the usenix > tapes prove. By the way, what does "professional" mean ?? > Someone making a living thru programming ??? ... Professionalism is defined by behavior, not credentials. As your examples amply demonstrate. -- Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,linus,decvax}!utzoo!henry
larry@cca.UUCP (Laurence Schmitt) (07/19/85)
>> 3) Is there really much to be gained by using assignment within >> a boolean expression, for example, is >> >> if ((fp = fopen("foo", "r") == NULL) { >> >> really that much faster than >> >> fp = fopen("foo", "r"); >> if (fp == NULL) { > >Again, depends: if "fp" is not a register, the assignment+test is faster, >since you end up branching after the assignment from r0 to "fp". If it >is a register, it comes out the same. (At least after optimization, usually). >The first form is never slower, anyway. In Lattice C on the IBM-PC the two constructs compile exactly the same--no register declarations involved.
gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (07/25/85)
Professionalism is an attitude. It is not restricted by age or means of income. This whole discussion started when someone complained that standard C idioms should not be used because they made it harder for unqualified people to read C code. One of the hallmarks of a professional is skilled use of his tools.. Would someone explain why it is important for code to be understood by untrained people? (This is truly impossible, in any case, except for rather trivial examples. An untrained person is unlikely to understand linked data structures, dynamic memory allocation, recursion, etc.) Certainly, many people who are getting paid to program in C are doing a terrible job of it. Certainly, it is possible to produce obscure code in C. Professional programmers do their best to produce good code (by all relevant standards, including maintainability) under existing constraints (time being a major factor).