[net.lang.c] C programming style

DHowell.ES@Xerox.ARPA (07/09/85)

Let me start out by saying that while I am not an experienced C
programmer, I am an experienced programmer.  These replies are based on
my limited knowledge of C, but I believe they are applicable to all
programming languages in one way or another.

>Ok, I give up!  Tell me how is it easier to find out what fp is when it
>is on a single line.  You find out what fp is by printing out its
value.
>You might also explain why someone would NOT want to reference fp again
>[In other words, why would you open a file for reading if you didn't
>want to read from it?]

If I am using a C interpreter, I could find out what fp is by printing
out its value.  However, when I am looking at the program on paper, and
I see the variable "fp" being used, I want to find out what fp is
representing.  If I see the statement "fp = fopen("foo", "r");", where
fp is at the beginning of a line then I know that fp is referring to the
file "foo".  But if I have to look for it in an if statement, then it's
that much harder to understand.  Sure I can understand it, and
"experienced C programmers" can understand it, but is everyone you're
working with an "experienced C programmer"?

>Typing has nothing to do with it, "i++" is clearer than "i = i + 1" to
me,
>especially (as someone else has pointed out) when 'i' is a longish
expression.

Maybe "i++" is clearer to you, but do you only write programs for
yourself?  To me "i++" is the kind of statement typical of an APL-type
language, not a language that is supposed to be structured and easy to
understand.  "i++" could mean something else in another language.  But
almost all high level languages (even APL) use some form of "i = i + 1"
to increment a variable.  If I want to distinguish between incrementing
and adding, then I would define a procedure such as "increment(i)",
which can be immediately understood.

If you completely understand the problem you're solving, and you are
working with no one but yourself, by all means use whatever cryptic
language idioms you want.  But if you are writing for someone else,
remember that the person who understands the *problem* may not
understand the programming language.  Do whatever you like as long as
you can explain it to the person who knows what he/she wants done.

Progams should be as language-independent as possible.  It shouldn't
matter whether the program is in C, Pascal, Ada, or even the dreaded
APL, but that it can be understood by *anyone* who needs to look at the
program.  If you limit that *anyone* to "experienced C programmers",
you're limiting the possibilities of that program.

Dan  /* comments are of course welcome */

tomk@ur-laser.uucp (Tom Kessler) (07/10/85)

>Maybe "i++" is clearer to you, but do you only write programs for
>yourself?  To me "i++" is the kind of statement typical of an APL-type
>language, not a language that is supposed to be structured and easy to
>understand.  "i++" could mean something else in another language.  But
>almost all high level languages (even APL) use some form of "i = i + 1"
>to increment a variable.  If I want to distinguish between incrementing
>and adding, then I would define a procedure such as "increment(i)",
>which can be immediately understood.

i don't know about you but my c compiler generates 3 fewer instructions
and does all of the adding in registers when i user i++ instead of i = i + 1.
-- 
--------------------------
		   Tom Kessler {allegra |seismo }!rochester!ur-laser!tomk
Laboratory for Laser Energetics               Phone: (716)- 275 - 5101
250 East River Road
Rochester, New York 14623

preece@ccvaxa.UUCP (07/11/85)

> > Typing has nothing to do with it, "i++" is clearer than "i = i + 1" to
> > me, especially (as someone else has pointed out) when 'i' is a longish
> > expression.
>
>  Maybe "i++" is clearer to you, but do you only write programs for
> yourself?  To me "i++" is the kind of statement typical of an APL-type
> language, not a language that is supposed to be structured and easy to
> understand.  "i++" could mean something else in another language.  But
> almost all high level languages (even APL) use some form of "i = i + 1"
> to increment a variable.  If I want to distinguish between incrementing
> and adding, then I would define a procedure such as "increment(i)",
> which can be immediately understood.
----------
I try not to write "i++" as a statement, though I use it in for
statements, of course.  But I NEVER write "i = i + 1", always using
the form "i += 1", which conveys the obvious information that this is
an increment rather than a generic assignment.  If the language provides
a way for you to tell the compiler more about what you're doing, use it.
I also would claim that a form specifically indicating that you're
incrementing a value is clearer to the reader, especially the relatively
inexperienced reader.  The form "i = i + 1" is a text-book example of
a concept difficult for beginners to understand.
----------
> Progams should be as language-independent as possible.  It shouldn't
> matter whether the program is in C, Pascal, Ada, or even the dreaded
> APL, but that it can be understood by *anyone* who needs to look at the
> program.  If you limit that *anyone* to "experienced C programmers",
> you're limiting the possibilities of that program.
----------
I submit that the phrase "least common denominator," applied to
anything but its mathematical meaning, is pejorative.  Society respects
those who use tools WELL.  That usually means idiomatically. No, I don't
believe in performing professional tasks with undue attention to the
needs of unprofessional successors, except where that is a specific
goal (writing, for instance, code intended to be modified by end users).
It is VITAL to make code clear and understandable, but it is not
necessary to assume that the person reading it doesn't know the
language.

Some people seem to think that idioms exist to obscure meaning.  Nothing
could be further from the truth.  Idioms provide insight into meaning,
to those who know the language.  Idioms arise because they are natural
ways to express something:  a person does something in a way that seems
natural and others, seeing that expression and finding it pleasing,
adopt it.  Idioms help the reader figure out what is going on.

-- 
scott preece
gould/csd - urbana
ihnp4!uiucdcs!ccvaxa!preece

ron@brl-tgr.ARPA (Ron Natalie <ron>) (07/12/85)

> >Maybe "i++" is clearer to you, but do you only write programs for
> >yourself?  To me "i++" is the kind of statement typical of an APL-type
> >language, not a language that is supposed to be structured and easy to
> >understand.
> i don't know about you but my c compiler generates 3 fewer instructions
> and does all of the adding in registers when i user i++ instead of i = i + 1.
> -- 
Oh foo, it ain't all that hard to understand, especially for systems programmers
who were the target group the language was written for.  It's a very obvious
carry over from index mode operations that most assemblers use.

-Ron

mdavis%Nosc@crash.ARPA (07/12/85)

On the matter of "i++": I guess it all depends on whether you want to write
code that looks good or code that runs well.

Morgan Davis -- {ihnp4, cbosgd, sdcsvax, noscvax}!crash!mdavis
                crash!mdavis@ucsd  -- or --  crash!mdavis@nosc

franka@mmintl.UUCP (Frank Adams) (07/12/85)

In article <11434@brl-tgr.ARPA> DHowell.ES@Xerox.ARPA writes:
>Let me start out by saying that while I am not an experienced C
>programmer, I am an experienced programmer.  These replies are based on
>my limited knowledge of C, but I believe they are applicable to all
>programming languages in one way or another.

I am an experienced programmer.  I have been writing C for about four
months now.

>Maybe "i++" is clearer to you, but do you only write programs for
>yourself?  To me "i++" is the kind of statement typical of an APL-type
>language, not a language that is supposed to be structured and easy to
>understand.  "i++" could mean something else in another language.  But
>almost all high level languages (even APL) use some form of "i = i + 1"
>to increment a variable.  If I want to distinguish between incrementing
>and adding, then I would define a procedure such as "increment(i)",
>which can be immediately understood.

I agree that "i++" is an abomination.  (I do use it, however, to be
consistent with the rest of the code I work with.)  Actually, C has
a third way to represent this operation: "i += 1".  Personally, I
think this is the superior notation.  It is concise, yet easy enough
for a person unfamiliar with the language to interpret.

Incidently, "i = i + 1" is not all that obvious, either.  Many people's
response, on seeing such an expression for the first time, is "impossible.
'i' can't equal 'i + 1'.".

ned@SCIRTP.UUCP (Ned Robie) (07/13/85)

> Progams should be as language-independent as possible.  It shouldn't
> matter whether the program is in C, Pascal, Ada, or even the dreaded
> APL, but that it can be understood by *anyone* who needs to look at the
> program.  If you limit that *anyone* to "experienced C programmers",
> you're limiting the possibilities of that program.
> 
> Dan  /* comments are of course welcome */

I disagree.  If programs were written to be as "language-independent" as
possible, what kind of languages would we be using???  Wouldn't this have
the net effect of significantly slowing the evolution of computer language?

I mainly program in C and Pascal, but I'm very glad that I had the opportunity
to learn and use APL.  It is a unique language with many good ideas.  It is
not perfect, but then no language is.  It is not effective in all applications;
no language that I'm aware of is.  But I found it to be a refreshing, exciting,
and fun(!) way to solve problems.  Best of all, it made me a better programmer.

The short-term benefits of *everyone* programming in compliance with the
current popular semantic model are appealing, but the long-term results
would be to retard the research and development of other forms of human/
computer communication.  In light of the fact that many of today's problems
cannot be adequately expressed to a machine, this would be a grave mistake.

-- Ned Robie

stew@harvard.ARPA (Stew Rubenstein) (07/15/85)

Summary: i++ leads to confusion, but ++i is often an excellent alternative.

In article <480@mmintl.UUCP> franka@mmintl.UUCP (Frank Adams) writes:
>
>I agree that "i++" is an abomination.  (I do use it, however, to be
>consistent with the rest of the code I work with.)  Actually, C has
>a third way to represent this operation: "i += 1".  Personally, I
>think this is the superior notation.  It is concise, yet easy enough
>for a person unfamiliar with the language to interpret.

One opinion that I haven't heard expressed:  I, too, agree that "i++" is
not the greatest.  But why do people always use this postfix form when
the prefix form, "++i", is available?  From my vantage point as a long-
time programmer, it is hard to say with certainty, but isn't it a whole
lot more clear that ++ is an operator and is doing something to "i" in
this case?

The only excuse for i++ is that you want to use the value before
incrementing.  A good compiler, or a very bad one, might generate better
code in some cases where i++ is used for its value, but frequently this
results in the program doing extra work to stuff the old value in a
temporary until the expression is evaluated!  There are some common
constructs in which i++ (or ptr++) is useful, but in the hands of many
programmers, this construct leads to confusing statements performing
two unrelated functions.

>Incidently, "i = i + 1" is not all that obvious, either.  Many people's
>response, on seeing such an expression for the first time, is "impossible.
>'i' can't equal 'i + 1'.".

Once a beginning programmer learns about assignment statements, this is
a non-issue.  It would be nice if we had chosen some other character,
but someone decided that underscore was more important than left-arrow
back in the 60's, and now we're stuck.

jcm@ornl-msr (James A. Mullens) (07/15/85)

The discussion of programming style reminds me of TV's endless commercials
telling me "Pepsi tastes better", "the new Coke tastes better", etc.  Next
we'll have "taste tests" in which people will be asked to choose between
i++ and i+1.  The tests will show that 55% choose i++, and someone will try
to tell me that I should use i++ just because "most people prefer it".
Bull!  I know what tastes better to me, and I don't need someone else to
tell me!

rdp@teddy.UUCP (07/15/85)

One of the points with the C i++ versus i = i = 1 issue is the one of
pointers (although some alluded to it).

Say we have some item like:


	main(argc, argv)
	int argc;
	char **argv;

stepping through the array of pointers can be done by by incrementing
a pointer:

	while (condition) /* or some other loop construct */
	  . . . 

	  argv++;

This will get us to the next pointer, whereas,

	  argv = argv + 1;

will NOT (unless by the happy happinstance that a pointer is exactly
the same size as a character!)

The only equivalent "clear" statement would be:

	argv = argv + sizeof(char *); !

I am not fond of the i++ idiom myself, however, the original author
severely oversimplified his case, I am afraid. 

After reading many dozens of messages going back and forth over this issue,
my own conlusion is that one can program simply using the absolute minumum
of idioms, one can cleverly use idioms that result in completely incomprehensible
code, or one can design simply, properly use the tools available, and develop
code that is conceptually simple, and uses the best of the tools in a way
which is understandable, repairable and extendable.


	

braun@drivax.UUCP (Karl Braun) (07/15/85)

> Maybe "i++" is clearer to you, but do you only write programs for
> yourself?  To me "i++" is the kind of statement typical of an APL-type
> language, not a language that is supposed to be structured and easy to
> understand.  "i++" could mean something else in another language.  
> ... If I want to distinguish between incrementing
> and adding, then I would define a procedure such as "increment(i)",
> which can be immediately understood.

var++ or ++var is a basic primitive of C.  If you don't immediately comprehend
what var++ means, then you don't know C (as in, haven't even looked at the
manual).  It is exactly equivelant to a procedure 'increment(var)'.

Yes, maintenance costs more than original program development and it's costs 
should be weighed against development costs, but, as I think most C programmers
would agree, this particular statement is so fundemental to the language that
is kind of silly not to use it.  The comment regarding the effeciency of the
produced code is probably applicable to most compilers, but academically, any
reasonable optimizer should optimize 'i = i + 1' to equivelant code.  

I guess the main point is this:  if you don't understand 'var++' then you
probably are not quite ready to be upgrading C code.

franka@mmintl.UUCP (Frank Adams) (07/15/85)

In article <11515@brl-tgr.ARPA> ron@brl-tgr.ARPA (Ron Natalie <ron>) writes:

>  It's (i++) a very obvious
>carry over from index mode operations that most assemblers use.
>
>-Ron

Most assemblers FOR WHAT MACHINE?  Never mind answering, I know.  Try
broadening your horizons a bit.

jerry@uwmcsd1.UUCP (Jerry Lieberthal) (07/15/85)

> The discussion of programming style reminds me of TV's endless commercials
> telling me "Pepsi tastes better", "the new Coke tastes better", etc.  Next
> we'll have "taste tests" in which people will be asked to choose between
> i++ and i+1.  The tests will show that 55% choose i++, and someone will try
> to tell me that I should use i++ just because "most people prefer it".
> Bull!  I know what tastes better to me, and I don't need someone else to
> tell me!

But, then you will have "new programming style", and, "Classic programming
style."  Maybe that way everyone will be be happy (if that's possible!).

john@genrad.UUCP (John P. Nelson) (07/16/85)

In article <935@teddy.UUCP> rdp@teddy.UUCP (Richard D. Pierce) writes:
>	char **argv;
>
>	  . . . 
>
>	  argv++;
>
>This will get us to the next pointer, whereas,
>
>	  argv = argv + 1;
>
>will NOT (unless by the happy happinstance that a pointer is exactly
>the same size as a character!)

Well, I personally like ++argv best, but the argument above is just NOT TRUE!
Referring to K&R page 94:

    int *pa

    . . .

    The definition of "adding 1 to a pointer", and by extension, all pointer
    arithmetic, is that the increment is scaled by the size in storage of the
    object that is pointed to.  Thus in pa+i, i is multiplied by the size of
    the objects that pa points to before being added to pa.

chris@umcp-cs.UUCP (Chris Torek) (07/16/85)

> Say we have some item like:
>	main(argc, argv)
>	int argc;
>	char **argv;
> stepping through the array of pointers can be done by by incrementing
> a pointer:
>		argv++;
> This will get us to the next pointer....
>		argv = argv + 1;
> will NOT (unless by the happy happinstance that a pointer is exactly
> the same size as a character!)

Nope.  In this case ``argv = argv + 1'' will get you to the next
pointer, just like ``argv++''.  See any C book, ``pointer arithmetic''.

The form ``lvalue += 1'' is always equivalent to ``++lvalue''
(though many compilers will generate different code for the two).
Furthermore, ``lvalue++'' is equivalent to ``++lvalue'' iff the
value of the expression is not used.  (Again, some compilers---not
many---may generate different code.)
-- 
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

jordan@greipa.UUCP (Jordan K. Hubbard) (07/16/85)

In article <935@teddy.UUCP> rdp@teddy.UUCP (Richard D. Pierce) writes:
>
>One of the points with the C i++ versus i = i = 1 issue is the one of
>pointers (although some alluded to it).
>
>	  argv++;
>
>This will get us to the next pointer, whereas,
>
>	  argv = argv + 1;
>
>will NOT (unless by the happy happinstance that a pointer is exactly
>the same size as a character!)


Note that I have not included enough of this gentleman's article to
fully outline his assertions, but in a nutshell, he claims that
pointer arithmetic does not work unless the unary operators are
applied. Um, I don't knoe which compiler HE'S using, but it must
be severely braindamaged (someone's thesis project?). According
to K&R and every C compiler I've ever used, this is simply not true.
pointer = pointer + 1 works fffffffffineee..

-- 
			Jordan K. Hubbard
			@ Genstar Rental Electronics.
			Palo Alto, CA.
			{pesnta, decwrl, dual, pyramid}!greipa!jordan

			"ack pfffft. gag. retch. barf.. ack"

				- Bill again.

guy@sun.uucp (Guy Harris) (07/16/85)

> 	  argv++;
> 
> This will get us to the next pointer, whereas,
> 
> 	  argv = argv + 1;
> 
> will NOT (unless by the happy happinstance that a pointer is exactly
> the same size as a character!)

Excuse me, but what alternate universe did you get your C Reference manual
from?  Both of the two above statements have the *exact same effect* in C;
they cause "argv" to point to the pointer that follows the one it pointed to
before the statement.

The C Reference Manual:

	7.2 Unary operators

	...The expression ++x is equivalent to x += 1.

	Guy Harris

oyster@uwmacc.UUCP (Vicious Oyster) (07/16/85)

In article <935@teddy.UUCP> rdp@teddy.UUCP (Richard D. Pierce) writes:
>
>One of the points with the C i++ versus i = i = 1 issue is the one of
>pointers (although some alluded to it).
>
>
>stepping through the array of pointers can be done by by incrementing
>a pointer:
>
>	while (condition) /* or some other loop construct */
>	  . . . 
>
>	  argv++;
>
>This will get us to the next pointer, whereas,
>
>	  argv = argv + 1;
>
>will NOT (unless by the happy happinstance that a pointer is exactly
>the same size as a character!)
>
>The only equivalent "clear" statement would be:
>
>	argv = argv + sizeof(char *); !
>
   I worked for a company which was (well, *is*, but going down fast) fond of
making everything proprietary (i.e. non-standard).  They came up with a 
language called DASL (*), based very strongly on C, which
actually perverted the meaning of arithmetic in such a way that 
"argv = argv + n" ACTUALLY MEANT "argv = argv + n*sizeof(argv *)" !!  That
wasn't documented anywhere, and we had one hell of a time with a certain 
piece of code until we figured out what was going on.
   For the record, I think the "++var" idiom is vastly preferable to making up
yet another idiom.

* DASL is a registered to Datapoint Corporation to denote their proprietary
  programming language.  And if I never see another DASL program in my life
  I'll die happy.

-- 
 - joel "vo" plutchak
{allegra,ihnp4,seismo}!uwvax!uwmacc!oyster

"Take what I say in a different way and it's easy to say that this is
all confusion."

kimcm@diku.UUCP (Kim Christian Madsen) (07/17/85)

In article <480@mmintl.UUCP> franka@mmintl.UUCP (Frank Adams) writes:
>
>I am an experienced programmer.  I have been writing C for about four
>months now.

Does that make you a experienced C programmer ???? (-;

>I agree that "i++" is an abomination.  (I do use it, however, to be
>consistent with the rest of the code I work with.)  Actually, C has
>a third way to represent this operation: "i += 1".  Personally, I
>think this is the superior notation.  It is concise, yet easy enough
>for a person unfamiliar with the language to interpret.

The main advantage of the ++ or -- notation in C is that you can construct
a loop and control the increment-variable [let's call it ``i'' for the old
Fortran days] by means of ++i or i++ in order to assure that ``i'' has the
proper value after the loop -- instead of +/- 1 which is the default in many
other languages as Pascal/Fortran/Basic etc...

--Kimcm@diku.uucp

scott@othervax.UUCP (Scott Pace) (07/17/85)

In article <935@teddy.UUCP> rdp@teddy.UUCP (Richard D. Pierce) writes:
>
>One of the points with the C i++ versus i = i = 1 issue is the one of
>pointers (although some alluded to it).
>
>Say we have some item like:
>
>
>	main(argc, argv)
>	int argc;
>	char **argv;
>
>stepping through the array of pointers can be done by by incrementing
>a pointer:
>
>	while (condition) /* or some other loop construct */
>	  . . . 
>
>	  argv++;
>
>This will get us to the next pointer, whereas,
>
>	  argv = argv + 1;
>
>will NOT (unless by the happy happinstance that a pointer is exactly
>the same size as a character!)
>
>The only equivalent "clear" statement would be:
>
>	argv = argv + sizeof(char *); !
>

BULLSHIT!!!

Turn to page 96 of K&R.

Quoted without permission:

"5.4  Address Arithmetic

	If p is a pointer, then p++ increments p to point to the next
element of WHATEVER kind of object p points to, AND p+=i increments p
to point i elements beyond where it currently does."


So if we say i has the value 1;

p++
++p
p+=i

and since p+=i is equivalent to p = p + i

all four forms have EXACLTY the same effect on p.

And in our case:

++argv
argv++
argv+=1
argv=argv+1

are ALL EQUIVALENT!!!

Read the book next time.

Scott Pace, Philips Info. Sys. Ltd., Montreal, Canada

philabs!micomvax!othervax!scott

tooch@avsdS.UUCP (Michael J. Tuciarone) (07/17/85)

Awww, c'mon folks.

This whole discussion has become become silly enough  without  it
degenerating  into  flames  concerning  "professionalism"  and so
forth. If you're reading this, someone is sufficiently  convinced
of your qualifications that they gave you a computer account. (Or
at least you know enough not to break things.) If you can *write*
to  the net, you are able to wade through Unix [tm blah blah] do-
cumentation and operate the system and programs...de facto, not a
rank amateur.

Regardless, this is not net.flame. Let's try  to  have  a  little
professional courtesy and keep it clean, ok?

And about "style" and "idiom"...Computer languages are  generally
designed  to  either fit a particular application (e.g. C, Forth,
Ada) or demonstrate a principle (e.g., Pascal, APL, Lisp).  Easy,
easy,  flames  off. The utility of a language is inseparable from
its features and syntax, which in turn are  wholly  dependent  on
the  underlying design concept. With respect to C, the very first
sentence in "The C Programmer's Manual" (you all *do* have a copy
of  K&R,  don't  you?) reads, "C is a general-purpose programming
language which features economy  of  expression,  modern  control
flow and data structures, and a rich set of operators."

Increment and decrement operators, conditional  expressions,  and
returned values from assignment statements are not just a part of
C, they are accepted and preferred usage. One of the  great  vir-
tues  of  C  is its (potential) brevity and elegance; "economy of
expression" is a design goal of the language!  The  conscientious
programmer, like any skilled craftsman, will eschew opaque or in-
comprehensible constructions. But idioms such as:

        char buf[80], *cp = buf;

        while ( (*cp++ = getchar()) != '0 )
                ;

are common, short, and understandable at a glance to the program-
mer. Phrases like the above are the heart of C. I moved to C from
Pascal and never looked back, if only because I could finally fit
the whole function on one screen.

There is, in any language, a certain overhead involved in  learn-
ing  the  language  and its idioms. But all living languages will
develop their own shorthand and common expressions. Good program-
mers,  like users of *any* language, will note the expressions in
common use, and further those that are elegant, simple,  and  ex-
pressive while avoiding the unclear and confusing.

C may never approach Pascal for sheer readability, but the trade-
off  made  in  favor  of brevity and richness of expression seems
well worth the small extra effort invested in learning  to  speak
the language well.

Hoping you're still awake,
Mike Tuciarone
...{hplabs, ucbvax}!atd!tooch@avsdS
Audio/Video Systems Division
Ampex Corporation
"One of the [Allied-]Signal Companies"

brooks@lll-crg.ARPA (Eugene D. Brooks III) (07/18/85)

> I agree that "i++" is an abomination.  (I do use it, however, to be
> consistent with the rest of the code I work with.)  Actually, C has
> a third way to represent this operation: "i += 1".  Personally, I
> think this is the superior notation.  It is concise, yet easy enough
> for a person unfamiliar with the language to interpret.

The use of i++ when i+=1 will do is certainly an abomination!  I personally
always use i+=1 when i just want to increment i but an not going to use
its value in that expression.  For instance

	for(i = 0; i < DIM; i += 1)

People ask me WHY?  As it noted above everyone just uses i++.

I reserve the ++ and -- operators for when I an really doing something
special, incrementing or decrementing and using the value that existed BEFORE
the operation.  The occurence of ++ or -- in a program is a red flag telling the
reader that something very special is happening.

If you use ++ or -- when you simply want to decrement or increment then the
cases when its important to note the ordering of the operation and the returned
value of the expression get lost in the forest of ++s and --s an you get left
with buggy code.  Its the very much the crying wolf syndrome!

drg@rlvd.UUCP (Duncan R. Gibson) (07/18/85)

Re: i++ and i = i + 1

As an aside, I remember being taught AlgolW as a student, where i := i + 1
and i := 1 + i were equvalent statements, and incremented i. I then moved to
PL360 (yuk!) for a while where i := i + 1 inrements i, and i := 1 + i sets i
to 2.

This caught a lot of students out, especially as the two languages can be
made to look similar. At least i++ and ++i are *obvious* if you  have read
*any* introductory text to C.

bright@dataio.UUCP (Walter Bright) (07/18/85)

In article <1286@uwmacc.UUCP> oyster@uwmacc.UUCP (Vicious oyster) writes:
>   I worked for a company which was (well, *is*, but going down fast) fond of
>making everything proprietary (i.e. non-standard).  They came up with a 
>language called DASL (*), based very strongly on C, which
>actually perverted the meaning of arithmetic in such a way that 
>"argv = argv + n" ACTUALLY MEANT "argv = argv + n*sizeof(argv *)" !!  That
>wasn't documented anywhere, and we had one hell of a time with a certain 
>piece of code until we figured out what was going on.

I've been laboring under the impression that this is how C is defined
to work!

hwe@lanl.ARPA (07/18/85)

The original purpose of:
	char *p;

	while (*p++)...

was to allow the PDP-11 auto increment mode to be exploited.
The code above would generate something like...

	tstb @(r0)+

while the code:
	while (*p)
		p += 1;
would/could (depending on the smarts of the compiler) generate an "inc"
instruction.

In discussions of C, the following points should be remembered...

1.	The inventors (Ritchie and friends) of C were GOOD assembly
	programmers who recognised the utility of the new-fangled
	structured concepts.

2.	C was primarily a vehicle for VERY GOOD assembly language
	programmers to take advantage of the new structured programming
	while keeping the close-to-the-machine power needed (??) for
	system programming.

While I do support active discussions of programming style, p++ vs p += 1
and so on, have deeper significance than just style.
				Skip Egdorf

arnold@ucsfcgl.UUCP (Ken Arnold%CGL) (07/19/85)

In article <186@drivax.UUCP> braun@drivax.UUCP (Karl Braun) writes:
>The comment regarding the effeciency of the
>produced code is probably applicable to most compilers, but academically, any
>reasonable optimizer should optimize 'i = i + 1' to equivelant code.  

(I have extracted this out of an article I otherwise agreed with
completely, because this is not true, as will be elucidated below).

This is quite true for such simple expressions as
	i = i + 1;
but not true at all for such things as
	a[f()] = a[f()] + 1;
which cannot be reduced to
	a[f()]++;
Which is another reason why this can't be done.

Another thing which ++ saves is typos.  If you use
	i = i + 1;
you must retype "i".  This is fine when "i" is simple, but if it is
a complex variable expression, you could get two legal expressions which
are different instead of the same, and then not get the same effect
(not to mention the efficiency).

All in all, if "increment(i)" is more clear than "i++", you don't know
C.  Since ++ means "increment", nothing could be clearer.  Or would you
prefer "and", "or", "plus", "minus", etc.?  Urg.

		Ken Arnold

tooch@avsdS.UUCP (Michael J. Tuciarone) (07/19/85)

Dammit! Nroff zapped me again!

The line in my previous posting <74@avsdS.UUCP> which read

>         while ( (*cp++ = getchar()) != '0 )
>                 ;

and was supposed to be a glorious example of good C style
that would, shining before us like the Holy Grail, lead us
to the Promised Land of Good Coding Practices...
                                                got screwed up. 
It was *supposed* to read

         while ( (*cp++ = getchar()) != '\n' )
                 ;                       ^^^

Thus does the Master, whilst enlightening the Novices, fall flat
upon his Ass. Flames will be received in long-suffering silence.

Mike Tuciarone
...{hplabs, decvax}!atd!tooch@avsdS

And hey...hey!...HEYY!!!
	...Let's be *careful* out there.

lcc.niket@UCLA-LOCUS.ARPA (Niket K. Patwardhan) (07/19/85)

I am not sure whether you implied C does not interpret

argv = argv + n

as

argv = argv + n*sizeof(argv *)   (treating everything like an int).
According to the reference manual, adding an int to a pointer (however you do
it) adds enough to the pointer that the new value points to the object n
elements away from the original object pointed to. Thus C does the same thing
as DASL.

oyster@uwmacc.UUCP (Vicious Oyster) (07/19/85)

In article <13@brl-tgr.ARPA> lcc.niket@UCLA-LOCUS.ARPA (Niket K. Patwardhan) writes:
>I am not sure whether you implied C does not interpret
>
>argv = argv + n
>
>as
>
>argv = argv + n*sizeof(argv *)   (treating everything like an int).
>According to the reference manual, adding an int to a pointer (however you do
>it) adds enough to the pointer that the new value points to the object n
>elements away from the original object pointed to. Thus C does the same thing
>as DASL.

   Yeah, you're right.  I still think it sucks swamp water.  People who enjoy
touting the language they use (e.g. C) over, say, Fortran, generally come up
with negative examples like the infamous "Fortran redefining the value of
constants" feature.  I submit that equating a globally recognized set of
constants (i.e. the set of integers) with values that differ depending on
whatever program variable happens to be nearest to them is guaranteed to be
misleading.  Especially when, as I stated in my original posting, it is not  
documented (for DASL, not C).  To my trained and experienced mind, incrementing
and adding a constant are very different things (and C programmers and
language developers are not gods :-).

(Disclaimer for those who believe that a person's greatness depends upon
his or her knowledge of C minutae:  I coded in C only during my few years
in college; I worked with a C-like language in the real world, and now,
among other things, support a Pascal compiler (blecch!)).
-- 
 - joel "vo" plutchak
{allegra,ihnp4,seismo}!uwvax!uwmacc!oyster

"Take what I say in a different way and it's easy to say that this is
all confusion."

jss@sjuvax.UUCP (J. Shapiro) (07/20/85)

Teddy at GenRad writes:
> stepping through the array of pointers can be done by by incrementing
> a pointer:
> 
> 	while (condition) /* or some other loop construct */
> 	  . . . 
> 
> 	  argv++;
> 
> This will get us to the next pointer, whereas,
> 
> 	  argv = argv + 1;
> 
> will NOT (unless by the happy happinstance that a pointer is exactly
> the same size as a character!)

My recollection is that the integer is supposed to get converted to
the appropriate size pointer increment in such code. There are rules for
handling this sort of thing.  Though I may well be misreading, I think
Teddy has this one wrong.

Jon Shapiro

mjs@eagle.UUCP (M.J.Shannon) (07/20/85)

> To my trained and experienced mind, incrementing
> and adding a constant are very different things (and C programmers and
> language developers are not gods :-).
> -- 
>  - joel "vo" plutchak

The theory is this: if you declare a variable to point to a particular type of
object, you *should* be manipulating objects.  The compiler (or, more
precisely, the language specification) states that arithmetic on the pointer is
done in multiples of the object's size.

Since the expression *(E1+E2) is semantically equivalent to E1[E2], it is very
reasonable that the value of either expression is the object E2 ahead of E1, no
matter how big the object is.  Even fortran and pascal define the semantics of
indexing the same way.  Language consistency demands that pointer arithmetic be
defined as it is.

Yes, you can bitch & moan to your heart's content, but I (for one) will refuse
to (linearly) step through a symbol table like this:

	struct symtab {
		char * name;
		long value;
		int flags;
	};
	struct symtab symtab[1024];
	...
	for (sp = &symtab[0]; sp->name != NULL; sp += sizeof (struct symtab))
		...

when I should be able to say:

	...
	for (sp = &symtab[0]; sp->name != NULL; ++sp)
		...

(For nit-pickers, yes, there should be tests for reaching the end of the symbol
table, but the point here is to illustrate pointer manipulation.)
-- 
	Marty Shannon
UUCP:	ihnp4!eagle!mjs
Phone:	+1 201 522 6063

ark@alice.UUCP (Andrew Koenig) (07/20/85)

Joel Plutchak says:

> I submit that equating a globally recognized set of
> constants (i.e. the set of integers) with values that differ depending on
> whatever program variable happens to be nearest to them is guaranteed to be
> misleading.  

C doesn't redefine the integers; it defines addition and subtraction
on pointers.  That is: if p is a pointer to element n of an array
and i is an integer, then p+i is a pointer to element n+i of that
same array.  If p is a pointer to element n of an array and q is a
pointer to element k of the same array, then p-q is an integer and
has the same value as n-k.  What is so confusing about that???

ark@alice.UUCP (Andrew Koenig) (07/20/85)

> As an aside, I remember being taught AlgolW as a student, where i := i + 1
> and i := 1 + i were equvalent statements, and incremented i. I then moved to
> PL360 (yuk!) for a while where i := i + 1 inrements i, and i := 1 + i sets i
> to 2.

PL360 was unusual in that there was no operator precedence: all operators
(including assignment!) grouped to the left.  Thus i := 1 + i meant
(1) i := 1; (2) i := i + i;

Incidentally, it was possible in later versions of PL360 to increment i
by simply writing

	i + 1;

the idea being that writing an expression without an assignment
would use the first operand as its implicit destination.

And what about the =: operator?

	i + 1 =: j shl 2;

means: add 1 to i, put the result in j; now shift i left 2 bits.

arnold@ucsfcgl.UUCP (Ken Arnold%CGL) (07/20/85)

In article <74@avsdS.UUCP> tooch@avsdS.UUCP (Michael J. Tuciarone) writes:
>C may never approach Pascal for sheer readability, but the trade-
>off  made  in  favor  of brevity and richness of expression seems
>well worth the small extra effort invested in learning  to  speak
>the language well.

Mike makes several excellent points in this article (including an
appeal to professional courtesy from all of us professed
professionals), but I think he is being a bit oversimple here.
Readability is not a boolean value, but a vague factor with many
variables.  Some of these are language dependent (I always find APL
nearly impossible to read, for example; others may not, so maybe this
is "programmer+language dependent").  Others are programmer dependent.

C is very readable.  To me, it is more readable than PASCAL, because
its bandwidth of communication is higher, i.e., it uses nearly the full
ASCII set of characters instead of words.  I find it easier to scan C
code than PASCAL code because "and", "begin", "end", etc., have to be
read to distinguish them from variables, whereas &&, {, }, etc. are
easy to tell from variables.  The "richness of expression" of C
contributes to its readability WHEN you know the language.  When you
don't, it hurts.

This doesn't bother me.  The fact that I don't understand how my car
engine works never stopped me from driving it.  It would be nice if I
did understand all the techonology I use so that I can fix it when it
doesn't work, but I don't.  So I don't understand why people expect
programs to be understandable to everyone.  They tried that with COBOL,
and what they ended up with was a still unreadable language that nobody
wanted to program in (not that it stopped the bosses from wanting them
to).
		Ken Arnold

alexis@reed.UUCP (Alexis Dimitriadis) (07/21/85)

> > I agree that "i++" is an abomination.  
> 
> The use of i++ when i+=1 will do is certainly an abomination!  I personally
> always use i+=1 when i just want to increment i but an not going to use
> its value in that expression.  For instance
> 
> 	for(i = 0; i < DIM; i += 1)
> 
> People ask me WHY?  As it noted above everyone just uses i++.

  I realize comments like the above are coming from people who do not
claim long experience with C, but why all the excitement?  The meaning of

	foo++;

in a statement by itself (the context in which increment operators were 
attacked) should be absolutely clear to anyone who knows what `++' does.
Years of experience with kernel code are NOT required.  `foo++;' is also
terser than `foo += 1;' (or foo = foo + 1; !!!), and it's at least as
unambiguous.  The only blemish is, it doesn't _look_ like Pascal
or FORTRAN.

  Now about things like 

	while (*++ptr);

It _does_ take effort to decipher just what they do, even if you know
the language.  _That_ is unclear, and so are things like

	if (foo = scanf("%f", &num) != 1 || num > 0) 
		fubar();
	comment(foo);

that is, complex expressions without any parentheses to indicate what
is actually happening, or (all too often), if the "professional" 
who wrote it intended it to happen.  (There is a parenthesis error in our
ctime(), for example).  This kind of thing is unclear regardless of 
familiarity with the language.

  I do not agree that only "professionals" should use C, but there
is nothing wrong with using basic features of the language in a simple way.
I think it would be nice, in fact, if more people were familiar with
"structured" languages like C and Pascal.  (I wish the teaching of BASIC
would be made into a Federal offense!)  After all, the _big_ problems with
C  readability arise from use of its facilities in an obscure 
(e.g., unstructured) way, not from the choice of operators!

Alexis Dimitriadis
exit(errno ? (perror(argv[0]), errno) : 0);
/*NOTREACHED*/
-- 
_______________________________________________
  As soon as I get a full time job, the opinions expressed above
will attach themselves to my employer, who will never be rid of
them again.

             alexis @ reed

	         ...teneron! \
...seismo!ihnp4! - tektronix! - reed.UUCP
     ...decvax! /

guy@sun.uucp (Guy Harris) (07/22/85)

> I submit that equating a globally recognized set of constants (i.e. the
> set of integers) with values that differ depending on whatever program
> variable happens to be nearest to them is guaranteed to be misleading.

What changed is not the values of the integers but the operation implied by
the "+" operator.  pointer + N causes the pointer to point to the
object (of the type the pointer's type is derived from) N objects (*NOT* N
machine storage units) further into the array that "pointer" is assumed to
point to a member of.  This is a bit subtle, but a lot easier to understand
if you realize that pointers are NOT integers but abstract cookies referring
to objects in memory.  Most of the confusion stems from a too low-level
mental model of C; people think of pointers as integers indexing a memory
considered as a sequence of machine storage units instead of as the
aforementioned abstract cookies.

The fact that so many people have trouble with this is either because:

	1) The low-level model of memory and pointers is so ingrained into
	   programmer's consciousnesses that trying to make pointers a more
	   abstract model is doomed to failure

or

	2) C just hasn't been taught correctly - the instruction gives a
	   lower-level model than is appropriate.

The solution to 1) is to rip out pointer arithmetic, use arrays instead, and
have all C compilers do strength reduction to generate multiplication-free
code.  The solution to 2) is to avoid giving the impression that C is a
structured assembly language.

	Guy Harris

bright@dataio.UUCP (Walter Bright) (07/22/85)

>In article <186@drivax.UUCP> braun@drivax.UUCP (Karl Braun) writes:
>The comment regarding the efficiency of the
>produced code is probably applicable to most compilers, but academically, any
>reasonable optimizer should optimize 'i = i + 1' to equivalant code.  

Most Pascal and Fortran compilers will replace i=i+1 with i+=1 internally.
C compilers, however, usually don't bother because the i+=1 and ++i forms
are available, and the assumption is that they would have been used. These
comments also apply to all the op= forms in C.

Some C compiler trivia:
Since (i+=1) is exactly equivalent to (++i), most C compilers immediately
translate (++i) into (i+=1), and internally use the second one from then
on. Also, (i++) is usually internally translated to (i+=1) if the result
of the expression is not used. These kinds of conversions make life
easier for the code generator.

franka@mmintl.UUCP (Frank Adams) (07/24/85)

In article <1710@reed.UUCP> alexis@reed.UUCP (Alexis Dimitriadis) writes:
>> The use of i++ when i+=1 will do is certainly an abomination!  I personally
>> always use i+=1 when i just want to increment i but an not going to use
>> its value in that expression.  For instance
>> 
>> 	for(i = 0; i < DIM; i += 1)
>> 
>> People ask me WHY?  As it noted above everyone just uses i++.
>
>  I realize comments like the above are coming from people who do not
>claim long experience with C, but why all the excitement?

This is, in and of itself, a minor point.  The issue of readable code --
what it is and how important it is -- is not.  This is a minor battleground
of that larger discussion.

>  The meaning of
>
>	foo++;
>
>in a statement by itself (the context in which increment operators were 
>attacked) should be absolutely clear to anyone who knows what `++' does.
>Years of experience with kernel code are NOT required.  `foo++;' is also
>terser than `foo += 1;' (or foo = foo + 1; !!!), and it's at least as
>unambiguous.  The only blemish is, it doesn't _look_ like Pascal
>or FORTRAN.

We disagree here.  I think "foo += 1" is *significantly* more readable
than "foo++".  It is *insignificantly* less terse.  Both are, of course,
*perfectly* unambiguous, since they are specified by the C language
specification. :-)

However, I think "foo += 1" is better than "foo = foo + 1", because in
complex cases, it is both significantly terser, and significantly easier
to read.  Consider "(*foo)[bar]->shoe.shine += 1" versus
"(*foo)[bar]->shoe.shine = (*foo)[bar]->shoe.shine + 1".  Besides the
extra length, one must look closely to see that this is an increment,
and not, say, "(*foo)[bar]->shoe.shine = (*foo)[bar]->boot.shine + 1".
By contrast, "(*foo)[bar]->shoe.shine++" offers essentially nothing.

In other words, idioms are useful if they provide a significant improvement
in terseness, but not for a tiny improvement.

scott@othervax.UUCP (Scott Pace) (07/25/85)

Here is one (more?) reason to use assignments inside of conditional
statments which will especially appeal to those of you who like
efficiency in your code! (I hope this hasn't been mentioned before).


Consider the following piece of code:


int a,fp;

main()
{
    if ( (fp = open("foo",0)) < 0 )
	a = 1;
    fp = open("foo",0);
    if (fp < 0)
	a = 1;
}

Now, when this is compiled (VAX 780,4.1BSD) using the -S and -O
flags, the following assembly code is produced:
(the comments were added by me of course!!!)


.data
.comm	_a,4		;the 'a' variable
.comm	_fp,4		;the 'fp' variable
.text
LL0:.align	1
.globl	_main
.data	1
L19:.ascii	"foo\0"
.text
.data	1
L21:.ascii	"foo\0"
.text
.set	L14,0x0
.data
.text
_main:.word	L14
pushl	$0		;push the second (last) parameter to open
pushal	L19		;push the first parameter to open
calls	$2,_open	;call to open
movl	r0,_fp		;put returned value in fp (also setting cond. flags)
jgeq	L20		;do the 'if' part
movl	$1,_a		;a = 1 if fp < 0
L20:pushl	$0	;push the second (last) parameter to open
pushal	L21		;push the first parameter to open
calls	$2,_open	;call to open
movl	r0,_fp		;put returned value in fp (also setting cond. flags)
tstl	r0		;set the cond. flags again!!! - redundant instruction
jgeq	L22		;do the 'if' part
movl	$1,_a		;a = 1 if fp < 0
L22:ret			;exit


So we can see from this that the compiler produces more efficient
code when assignments are contained within a conditional such as
the 'if' statment.
It should be noted, however, that this is only one simple example
and that the above observation may not hold true in all cases.

Now, in this case one extra instruction isn't going to make any
difference but there may be other cases where the 'if' statment
is inside a loop and the loop body is executed thousands of times.
This extra instruction could mean a few extra seconds (or more!)
which may be critical in certain applications.

One final note, the compiler does NOT generate the extra instruction
when fp is declared as a register variable. It doesn't matter if
fp is declared auto or static or extern, all these types generate
the extra instruction except for a register declaration.

What we need is a good optimizer!!! (do I get a prize for stating
the obvious??!!)

Scott Pace,

	Philips Info. Sys. Ltd., Montreal.

	...!philabs!micomvax!othervax!scott

LINNDR%VUENGVAX.BITNET@WISCVM.WISC.EDU (09/01/86)

Since I am currently in a situation where I need the sort of behavior
described by Jeff Cavallaro in the original posting (an N step process
with abort on any failed step), I reread his text. I'm not read sure
how his example that "significantly upsthe routine count" is different
his preferred style example. In fact, his preferred style example look to
me to be what the compiler will actually produce for the

if (step1() && step2() && ... && stepn())

example (which I have simplified here by assuming that each step returns
a 1 for success).