Stylistic questions on UNIX C coding.

B

Ben Bacarisse

Rainer Weikusat said:
Ben Bacarisse said:
Rainer Weikusat said:
[...]

To count down through an array with N elements, I use

size_t i = N;

while (i-- != 0) {
array;
}

And you excuse for writing confusing code which requests that the
machine does useless things is that software to work around you has
already been developed, right?

Why not show everyone what you consider to be the right way to do this
so that we can all have the chance to write better/clearer loops? Not
everyone will agree, of course, but it is surely better to give
examples of good code than to criticise code you don't like.

Isn't this obvious? As written above, the calculation oversteps,
because the postdecrement will return zero when i already had this
value before decrementing it again.


What do you mean by "oversteps"?


Don't try to play 'stupid' with me. You understood me quite well, have
'surprisingly' completely ignored my text in order to construct a
straw man and are a live demonstration of the exact type of behaviour
I criticized. And very rightfully, sine I have to read quite lot of
code I didn't write myself and I claim to know something about the
problems the people who enjoy creating 'bunte Getueme' actually
fabricate.


No, I claimed you code was wrong whereas pete's was right.
 
N

Nick

Jerry Friedman said:
...

For those interested in what linguists have said about this, the terms
seem to be "topic" and "comment" or "theme" and "rheme". In English,
the topic usually goes before the comment. Of course even in a single
language the matter is complicated, and different linguists use
different approaches and different terminology.

(heading further and further OT) And one of the reasons that the
absolute "avoid the passive" rule is wrong is that sometimes it's much
easier to get the topic in the right place in a passive sentence than it
is in an active one.
 
E

Ersek, Laszlo

Rainer Weikusat said:
Ben Bacarisse said:
[...]

To count down through an array with N elements, I use

size_t i = N;

while (i-- != 0) {
array;
}

And you excuse for writing confusing code which requests that the
machine does useless things is that software to work around you has
already been developed, right?

Why not show everyone what you consider to be the right way to do this
so that we can all have the chance to write better/clearer loops? Not
everyone will agree, of course, but it is surely better to give
examples of good code than to criticise code you don't like.


Isn't this obvious? As written above, the calculation oversteps,
because the postdecrement will return zero when i already had this
value before decrementing it again.


What do you mean by "oversteps"? The code above works correctly when
N is zero and it executes the body exactly N times as it should.



Yes, but after that, "i" ends up as (size_t)-1. Compare:

size_t i = N;

while (0u < i) {
--i;

array;
array;
array;
}

Cheers,
lacos
 
K

Keith Thompson

Rainer Weikusat said:
Ben Bacarisse said:
Rainer Weikusat said:
[...]

To count down through an array with N elements, I use

size_t i = N;

while (i-- != 0) {
array;
}

And you excuse for writing confusing code which requests that the
machine does useless things is that software to work around you has
already been developed, right?


Why not show everyone what you consider to be the right way to do this
so that we can all have the chance to write better/clearer loops? Not
everyone will agree, of course, but it is surely better to give
examples of good code than to criticise code you don't like.


Isn't this obvious?


No -- or at least it's not nearly as obvious as you seem to think
it is.
As written above, the calculation oversteps,
because the postdecrement will return zero when i already had this
value before decrementing it again.

It does, but I don't think this is a significant problem. The most
common form of loop for iterating *up* through an array is:

for (i = 0; i < N; i ++) [
... array ...
}

oversteps the upper bound of the array.
Also, the condition is known to be
true so checking it before the first execution of the loop body is a
pointless exercise.

That's true *only* if you know that you're iteratingover the entire
array. What if N, rather than being the total number of elements in
the array, is the number of elements that you're current interested
in? (Say you're working with a counted string implementation.)
Then N could easily be 0.
A sensible way to express this in C would be

do array[--i]; while (i);

This fails rather catastrophically when N is 0.

Do you use a different form of loop when N can be 0 vs. when you know
it can't? If not, can you show us a loop that (a) iterates from
size_t values N-1 down to 0, (b) is as efficient as pete's loop,
and (c) is as clear to the reader as pete's loop?
This is politically incorrect for various reasons not the least one of
which is that people are often proud of having written code
thoughtlessly, presumably, because this demonstrate that it is below
their dignity to care for something as miniscule as that, and which
one will end up generating better code depends on the compiler and how
it was used. Eg, I have reason to suspect that at least some versions
of gcc transformate all loops to the 'condition in front of it'-form
(I don't know the English term for this, the German one would be
'abweisende Schleife') before they are feed to the various weird loop
optimizers intended to turn thoughtlessly written FORTRAN into
sensible machine code.

There's a good reason for that. Very often a while or for loop
is the clearest way to express some algorithm. The body of the
loop might not be executed at all. So an optimizing compiler might
transform this:

while (condition) {
something;
}

to the equivalent of this:

if (condition) {
/* ... */
do {
something;
while condition;
}

Everything within the body of the loop is executed N times, for
some N >= 0. If some of that code is loop-invariant, it can be
executed just once -- but if N is 0, it shouldn't be executed
at all. Loop-invariant code can be "hoisted" outside the loop.
The purpose of the transformation is to provide a place (marked
/* ... */) to which any loop-invariant code can be hoisted.

This *doesn't* imply that the programmer should have written the
if/do while version of the code in the first place. The while loop
is generally clearer to the reader than the transformed version,
and easier to maintain since the condition is only written once.
It requires the optimizer to do a tiny amount of extra work, but
that's its job.

[snip]

Our fundamental point of disagreement is that you seem to think
that pete's loop:

size_t i = N;

while (i-- != 0) {
array;
}

is not merely bad, but obviously bad, whereas I see nothing wrong
with it. The initial test is superfluous only if we know that N
0; I don't think leaving it in place is a significant problem,
worth restructuring the code. i is incremented again at the end,
leaving it with a value if SIZE_MAX after the loop; again, I don't
think that's a significant problem.

Indeed, if C had a higher-level loop construct for iterating over a
range of values:

for i in reverse 0 .. N-1 loop
...
end loop;

(that's Ada syntax), the compiler might well generate exactly the
same code as it does for pete's loop.
 
B

Ben Bacarisse

Rainer Weikusat said:
[...]

To count down through an array with N elements, I use

size_t i = N;

while (i-- != 0) {
array;
}

And you excuse for writing confusing code which requests that the
machine does useless things is that software to work around you has
already been developed, right?

Why not show everyone what you consider to be the right way to do this
so that we can all have the chance to write better/clearer loops? Not
everyone will agree, of course, but it is surely better to give
examples of good code than to criticise code you don't like.

Isn't this obvious? As written above, the calculation oversteps,
because the postdecrement will return zero when i already had this
value before decrementing it again.


What do you mean by "oversteps"? The code above works correctly when
N is zero and it executes the body exactly N times as it should.


Yes, but after that, "i" ends up as (size_t)-1.


That's why I asked -- just in case this what his complaint. It's not
one I'd worry about. In fact in some situations this is an advantage:
Compare:

size_t i = N;

while (0u < i) {
--i;

array;
array;
array;
}


If the loop body changes so that is includes some break statements,
pete's loop makes normal and abnormal loop exit easy to distinguish.
It's not a big deal, but I do prefer pete's formulation for this
reason.
 
E

Ersek, Laszlo

Ben Bacarisse said:
To count down through an array with N elements, I use

size_t i = N;

while (i-- != 0) {
array;
}

size_t i = N;

while (0u < i) {
--i;

array;
array;
array;
}


If the loop body changes so that is includes some break statements,
pete's loop makes normal and abnormal loop exit easy to distinguish.
It's not a big deal, but I do prefer pete's formulation for this
reason.


Yeah... I was thinking, "who will be the first one to say 'linear
search'?" :) "0u == i" doesn't say anything after the loop.

Cheers,
lacos
 
R

Rainer Weikusat

Keith Thompson said:
Rainer Weikusat said:
Ben Bacarisse said:
[...]

To count down through an array with N elements, I use

size_t i = N;

while (i-- != 0) {
array;
}

And you excuse for writing confusing code which requests that the
machine does useless things is that software to work around you has
already been developed, right?

Why not show everyone what you consider to be the right way to do this
so that we can all have the chance to write better/clearer loops? Not
everyone will agree, of course, but it is surely better to give
examples of good code than to criticise code you don't like.


Isn't this obvious?


No -- or at least it's not nearly as obvious as you seem to think
it is.


It is completely obvious from the difference of meaning of the code
which was written down vs the part of the code which actually performs
some sensible function. Spelled out, the condition means (assuming
that x is also a variable of type size_t)

x = i, i = i - 1, x != 0

Since the loop is only supposed to run until the counter has reached
the value zero, decrementing an i whose value is zero when the
condition is checked for the last time is just a pointless contortion.

It does, but I don't think this is a significant problem.

If you desire to argue against my position, why don't you do so? I
explained why I consider this to be a serious problem in the text
below.
The most
common form of loop for iterating *up* through an array is:

for (i = 0; i < N; i ++) [
... array ...
}

oversteps the upper bound of the array.


So, your reasoning goes roughly "well, ok, it is nonsense, but that's
what we always do". That you always write code which requests that
superflouus calculations are performed is no reason why doing so
should be desirable.
That's true *only* if you know that you're iteratingover the entire
array.

This is always true for the context the text which was following this
statement was supposed to make sense in. It doesn't matter what over
contexts you can dream up. That was the one I was using. Call it 'a
precondition' if you like.

[...]
A sensible way to express this in C would be

do array[--i]; while (i);

This fails rather catastrophically when N is 0.

It fails even more catastrophically when i was initially zero and
traversing the array in order of ascending indices was intended and
yet more catastrophically when, instead of traversing an array, the
string "Are you perhaps resorting to sophististry because you don't
have any arguments for your position" should have been printed. But
since none if this is/ was the case, that's quite besides the point.

If you desire to address the point I was trying to make, feel free to
do so. These sideline battles are useless exercises.
 
S

Seebs

ah! A disciple of Chompsky.I didn't know it had been proven beyond
doubt that such a Deep Structure existed

It hasn't been, but if you can find a counterexample to the claim that
people generally distinguish between topic and comment, I'd love to see it.
to write lisp you pretty well have to have support from your editor. I
seem to nest stuff deeper than most people- maybe this is something
computer programmers tend to do but lisp easily busts my internal
stack.

Yeah. I had some of that trouble with it.
I'll suffer the pain of an extra translation stage if I think it buys
me much. In this case I'd rather have the test the "right" way round.

In my case, I have a lot more bugs from cognitive stack overflows than I
have ever had from mistakenly assigning things in tests, so it makes sense
for me to pick the style that doesn't make the big problem dramatically
bigger. :)

-s
 
S

Seebs

Don't try to play 'stupid' with me. You understood me quite well, have
'surprisingly' completely ignored my text in order to construct a
straw man

This raises a question that, while not strictly topical, I find fascinating.

Have you found a set of circumstances in which declaring that you know what
other people think, and they are lying, has ever produced any kind of positive
or desireable outcome? Do you in fact have the telepathic ability you've
claimed, or are you just dogmatically proclaiming what someone else actually
thought without any kind of evidence or support?

-s
 
R

Rainer Weikusat

Rainer Weikusat said:
[...]
The most
common form of loop for iterating *up* through an array is:

for (i = 0; i < N; i ++) [
... array ...
}

oversteps the upper bound of the array.


So, your reasoning goes roughly "well, ok, it is nonsense, but that's
what we always do".


I should have read this more carefully :->. You are actually already
here (voluntarily) misinterpreting my statement, since none of the
increments which are supposed to be performed by the code quoted above
are technically useless, meaning, what I called 'overstepping the loop
counter' does not occur here. You are just hoping that a careless
reader (like me, for instance) takes your statement at face value,
without recognizing that you are already writing about a completely
different case.
 
R

Rainer Weikusat

Seebs said:
This raises a question that, while not strictly topical, I find fascinating.

Have you found a set of circumstances in which declaring that you know what
other people think, and they are lying, has ever produced any kind of positive
or desireable outcome?

I count your nice declaration as one, for example, since it
communicates more about you than about me.
 
S

Seebs

I count your nice declaration as one, for example, since it
communicates more about you than about me.

That's non-responsive.

You asserted that someone else understood what you meant, but you have done
nothing to show that this is true; instead, you just accused someone of
lying, without any evidence, and honestly, I don't see why you would expect
that someone would have understood you "quite well" and then "played stupid",
when it seems much more likely that someone misunderstood you.

It's Usenet. People *constantly* misunderstand each other.

I have not in general found that it is productive or rewarding to accuse
people of lying on the basis that they claim to have misunderstood me, because
for the most part, it turns out to be much more common that they actually
misunderstood me. Similarly, out of the hundreds of times people have
asserted that I knew something perfectly well, it has been true perhaps once
or twice. Usually, what's at issue is that I don't agree with them and
they'd prefer to use a violent and derisive response than acknowledge the
possibility of a genuine disagreement.

-s
 
K

Keith Thompson

Rainer Weikusat said:
Rainer Weikusat said:
[...]
The most
common form of loop for iterating *up* through an array is:

for (i = 0; i < N; i ++) [
... array ...
}

oversteps the upper bound of the array.


So, your reasoning goes roughly "well, ok, it is nonsense, but that's
what we always do".


No, my reasoning is "ok, this is a superfluous calculation, but that's
a trivial issue, not worth worrying about".
I should have read this more carefully :->. You are actually already
here (voluntarily) misinterpreting my statement, since none of the
increments which are supposed to be performed by the code quoted above
are technically useless, meaning, what I called 'overstepping the loop
counter' does not occur here. You are just hoping that a careless
reader (like me, for instance) takes your statement at face value,
without recognizing that you are already writing about a completely
different case.

It's entirely possible that I've missed some point you were trying
to make. It might even be my fault. I am not making intentional
mistakes and hoping that you'll miss them out of carelessness,
and I resent the accusation that I'm doing so.

The above loop iterates over array elements from 0 to N-1 inclusive.
On exit from the loop, i has the value N, which is one past the
desired range. This is very similar to what happens in pete's loop
that we were discussing upthread, though looking at it more closely
I see that i takes on values outside the desired range both before
and after the loop (it starts at N and ends up being (size_t)-1,
or SIZE_MAX).
 
K

Keith Thompson

Rainer Weikusat said:
If you desire to address the point I was trying to make, feel free to
do so. These sideline battles are useless exercises.

I was trying to address the point that (I thought) you were trying
to make. Perhaps if you could restate the point more clearly,
I could try again to respond to it. Answering the questions I
asked you might help.

Or you can continue to falsely accuse me of deliberate dishonesty,
and neither of us will learn anything. It's your call.
 
N

Nick Keighley

reinserted:

It hasn't been, but if you can find a counterexample to the claim that
people generally distinguish between topic and comment, I'd love to see it.

to be honest I just don't see this in normal english. People
describing events often intersperse the interpreation of events or
motivation with what happened. This is why (most )people make poor eye
witnesses.

The whole business about footnotes in formal documents is to make a
clear distinction that isn't normally made.

<snip>
 
S

Seebs

to be honest I just don't see this in normal english. People
describing events often intersperse the interpreation of events or
motivation with what happened.

That has absolutely nothing to do with the distinction between topic and
comment.
The whole business about footnotes in formal documents is to make a
clear distinction that isn't normally made.

But again, nothing to do with the distinction I'm talking about.

When someone says "the bear ate Bob", the bear is the topic, "ate bob" is
the comment. When someone says "Bob was eaten by a bear", Bob is the topic,
"was eaten by a bear" is the comment.

So far as I know, everyone makes this distinction. While it's not a hard and
fast rule, it's nearly always the case that the focus of discussion is the
topic of the sentence, not the comment. Thus, "the bear ate Bob" is a
statement by someone who is trying to talk about the bear, while "Bob was
eaten by a bear" is a statement by someone who is trying to talk about Bob.

They don't have quite the same semantics. One has the implication "and we
care about what the bear did", the other has the implication "and we care
about what happened to Bob".

-s
 
N

Nick Keighley

could you stop snipping so greedily! I had to back up twenty messages
to find the context.

***
Because he pronounces it as "x is not equal to y", and the subject of
that sentence is "x". "x" is the actor, the variable that is acting. "y"
is part of the prepositional phrase, it is static.

This is C we're discussing, not English. It is folly to pretend that
the
rules of English apply to C.
***


On 7 Mar, 22:14, Seebs <[email protected]> wrote:
to be honest I just don't see this in normal english. People
describing events often intersperse the interpreation of events or
motivation with what happened.

That has absolutely nothing to do with the distinction between topic and
comment. [...]
When someone says "the bear ate Bob", the bear is the topic, "ate bob" is
the comment.

this is a definition of "comment" I hadn't heard before. And an odd
one. Is it a technical term from linguistics or something?

So "topic" is what I'd call "subject" and "comment" is some sort of
"action"? A way to try and link psychology with OO programming?
 When someone says "Bob was eaten by a bear", Bob is the topic,
"was eaten by a bear" is the comment.

So far as I know, everyone makes this distinction.  While it's not a hard and
fast rule, it's nearly always the case that the focus of discussion is the
topic of the sentence, not the comment.  Thus, "the bear ate Bob" is a
statement by someone who is trying to talk about the bear, while "Bob was
eaten by a bear" is a statement by someone who is trying to talk about Bob.

They don't have quite the same semantics.  One has the implication "and we
care about what the bear did", the other has the implication "and we care
about what happened to Bob".

And how does this apply to

if (3 == thingy)
do_something_with (thingy);

There are some pretty odd computer languages out there (APL, Lisp,
Forth, ML, prolog). People seem to write useful applications in them.
There are some pretty odd (to us) natural languages out there. But
three year olds learn them.

I'm very dubious about any argument that uses (cod?) psychology to
justify language choice (that way lies Perl!). Human beings (and, I
think programmers) are very flexible in what they find lingusitically
acceptable. I don't like 3 == thingy but I don't think it relates to
my cortextual wiring.


--
The use of the Chomsky formalism is also responsible for the term
"programming language", because programming languages seemed to
exhibit a strucure similar to spoken languages. We believe that
this term is rather unfortunate on the whole, because a programming
language is not spoken, and therefore is not a language in the true
sense of the word. Formalism or formal notation would have been
more appropriate terms.
Niklaus Wirth
 
M

Malcolm McLean

Nick said:
This is C we're discussing, not English. It is folly to pretend that
the rules of English apply to C.
The keywords are English, with meanings related to their everyday non-
computer usage. (The exception maybe is "static").
In English we tend to say "x + 5" rather than "5 + x", "draw a point
at x, y" rather than "draw at y, x", 1/x rather than x^-1. It's all
purely conventional and without mathematical meaning, but it is the
way people talk. When computer code reflects those conventions it is
easy to read.
x equals 5 rather than 5 equals x is a particularly strong convention.
 
S

Seebs

could you stop snipping so greedily! I had to back up twenty messages
to find the context.
Sorry!
Because he pronounces it as "x is not equal to y", and the subject of
that sentence is "x". "x" is the actor, the variable that is acting. "y"
is part of the prepositional phrase, it is static.

This is C we're discussing, not English. It is folly to pretend that
the
rules of English apply to C.
It hasn't been, but if you can find a counterexample to the claim that
people generally distinguish between topic and comment, I'd love to see it.
to be honest I just don't see this in normal english. People
describing events often intersperse the interpreation of events or
motivation with what happened.

That has absolutely nothing to do with the distinction between topic and
comment. [...]
When someone says "the bear ate Bob", the bear is the topic, "ate bob" is
the comment.

this is a definition of "comment" I hadn't heard before. And an odd
one. Is it a technical term from linguistics or something?

Yes. And one which someone had recently pointed out in-thread.
So "topic" is what I'd call "subject" and "comment" is some sort of
"action"? A way to try and link psychology with OO programming?

Comment is what you're saying about the subject. Not really "action" -- more
"information". "The ball is red" is not telling you about something the ball
*does*, but giving you information about its qualities.

And there's a big difference between "The ball is red" and "The red thing is a
ball" in English.
And how does this apply to
if (3 == thingy)
do_something_with (thingy);

In
x == y

It is most often the case that x is topic, y is comment. Which is to say,
we are comparing a thing we are interested (x) in to a value we aren't
particularly expecting to change (y) but which would tell us about it.

In general, if I have a loop:
while (x != y) {
}

two things are true:
1. I almost certainly expect x to change during the loop, and y not to
change during the loop. It's not a guarantee, but if you check all the
code out there, in books, in real world code, etcetera, you'll find that
it's true nearly all the time. The only exceptions are people writing
it "backwards" and cases where both are subject to change.
2. A future reader of my code is, as a result, more likely than not to
at least initially make that assumption.

Having that assumption change if, and only if, y is a constant, is extremely
surprising.

Now, if you ALWAYS wrote it the other way -- if you always wrote "max > i"
rather than "i < max", etcetera -- people would probably find it less
confusing. It's that the natural order is consistently used except in
one specialized case that makes it so surprising.
I'm very dubious about any argument that uses (cod?) psychology to
justify language choice (that way lies Perl!). Human beings (and, I
think programmers) are very flexible in what they find lingusitically
acceptable. I don't like 3 == thingy but I don't think it relates to
my cortextual wiring.

I am in general skeptical of them, but the strength of the topic/comment
rule is manifest, and the large number of people who find it confusing
suggests that it really *is* confusing.

I would guess that, had early code not developed a convention, we might not
find it so confusing, but once the convention was established... Going
against it is like driving on the other side of the road because you've
become convinced that it is a technically superior choice.

-s
 
R

Rainer Weikusat

Keith Thompson said:
I was trying to address the point that (I thought) you were trying
to make. Perhaps if you could restate the point more clearly,
I could try again to respond to it.

I already restated my point in a somewhat more condensed way,

,----
| It is completely obvious from the difference of meaning of the code
| which was written down vs the part of the code which actually performs
| some sensible function. Spelled out, the condition means (assuming
| that x is also a variable of type size_t)
|
| x = i, i = i - 1, x != 0
|
| Since the loop is only supposed to run until the counter has reached
| the value zero, decrementing an i whose value is zero when the
| condition is checked for the last time is just a pointless contortion.
`----

You have again ignored this completely. Further, I posted an
explanation of the difference between this
postincrement-where-it-isn't-appropriate issue and you for loop:

,----
| since none of the increments which are supposed to be performed by
| the code quoted above are technically useless, meaning, what I
| called 'overstepping the loop counter' does not occur here.
`----

Because the test is basically while (i < N), i needs to be incremented
until i == N, while in order to test i != 0, no post-decrement down to
(unsigned)-1 needs to be performed. You still claim that both would be
identical while they are clearly not identical and anyone with sufficient
knowledge in C to understand the code at all can be expected to
understand the difference. Lastly, I specifically wrote (in the first
text whose content you have chosen to ignore) that I wouldn't be
writing about "optimizations issues", yet, you are trying to drag me
into a discussion of exactly that in the other posting.

Whatever your motivation for acting in this way might be, for as long
as you are basically attaching unrelated statements to random parts of
heavily redacted variants of texts I originally wrote, any attempt at
a 'discussion' is a waste of bandwidth.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top