Liste des Groupes | Revenir à cl c |
On 21/04/2025 14:51, Waldek Hebisch wrote:bart <bc@freeuk.com> wrote:>
I don't know why people think that cramming as much code as possible
into for(...) is a good style of coding. Either into one over-long line,
or spilling over multiple lines; both should fail a code review.
>
Actually here's a example from sqlite3.c:
>
for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){
sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p));
}
>
And this is how you might be forced to write it instead:
>
p=sqliteHashFirst(&pSchema->trigHash);
while (p) {
sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p));
p=sqliteHashNext(p);
}
>
Yes, it's spread over two more lines, but so what? It's much clearer:
the initialisation is done once and then it's out of the way. Setting p
to the next value is now physically written after the body.
Apparently you do not get why sqlite3.c version is better.
In short, this is separation of concerns. The 'for' construct
is responsible for iteration. Body of 'for' loop is responsible
for computation. You may replace body by empty instruction,
so there are no computation but the loop still correctly goes
over the same sequence. Or you may add instructions to perform
more computation. 'while' version mixes computation with
stepping to the next element. Since in 'for' version all parts
dealing with iteration are together it is easy to check that
they are correct. With 'while' version probablity of forgeting
to step to next element is higher.
You have to analyse it first. The kind of loop this expresses is:
p = startvalue()
while (p) {
<body>
p = nextvalue()
}
Notice how I chose to express it: it reflects how I would describe it in
English:
* Set P to Start Value
* While P isn't Null:
* Execute the body
* Set P to Next Value
So, how would /you/ describe it in English? (Or in any language if like,
as the ordering is more important.)
In short, this is separation of concerns.
You seem be picking and choosing which concerns are in need of separation!
The example is this: for(A; B; C) D
You are saying that D must be separate from A B C, but specifically from C.
I'm asking, why shouldn't A B C also be separate from each other?
Especially A, which is only executed once, after which it's no longer
part of the loop.
As C works now, the alternative might be: A; while (B) { D; C;}.
I wouldn't have minded a syntax like: A; while (B; C) {D} but C doesn't
have that. In that case, the 'while' version still wins over 'for' IMO.
FYI: I do not remember making error in a simple 'for' loop.
I do remember cases when I had to use 'while' for iteration
(in non-C languages) and stepping was wrong/missing. So
for me simple loops (your 98% of cases) are not an issue.The issue are remaining cases, and for them C 'for' works
better.
That's bizarre. It is exactly like saying you don't have a problem with
writing (or forgetting to write) 'break' in 99% of switch-case blocks,
because in those 1% of cases where you do want fallthroughit is 'automatic'.
I expect you also either think that:
for (ch = 0; ch <= 255; ++ch)
is better than: 'do ch = 0, 255', or is much more tolerant of it than I am.
Here's how that C for-loop works, in English:
* Set ch to 0
* While c is less than or equal to 255: (typo left in!)
* Execute the body
* Set ch to ch + 1
Here is how that compact version works, in English:
* For ch having the values 0 to 255 inclusive:
* Execute the body
However I see that nobody in this group has any objective interest in
language ergonomics and aesthetics. They more interested in defending
'their' language.
Les messages affichés proviennent d'usenet.