Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #150237 > unrolled thread
| Started by | chad <cdalten@gmail.com> |
|---|---|
| First post | 2020-02-25 06:55 -0800 |
| Last post | 2020-02-27 15:28 -0800 |
| Articles | 20 on this page of 32 — 12 participants |
Back to article view | Back to comp.lang.c
After doing a lot of the problems on codingbat.com chad <cdalten@gmail.com> - 2020-02-25 06:55 -0800
Re: After doing a lot of the problems on codingbat.com Anton Shepelev <anton.txt@g{oogle}mail.com> - 2020-02-27 20:02 +0300
Re: After doing a lot of the problems on codingbat.com James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-02-27 11:41 -0800
Re: After doing a lot of the problems on codingbat.com Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2020-02-27 14:48 -0700
Re: After doing a lot of the problems on codingbat.com Bart <bc@freeuk.com> - 2020-02-27 23:17 +0000
Re: After doing a lot of the problems on codingbat.com James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-02-27 16:40 -0800
Re: After doing a lot of the problems on codingbat.com Bart <bc@freeuk.com> - 2020-02-28 01:08 +0000
Re: After doing a lot of the problems on codingbat.com Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-02-28 01:37 -0800
Re: After doing a lot of the problems on codingbat.com James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-02-28 06:21 -0800
Re: After doing a lot of the problems on codingbat.com Bart <bc@freeuk.com> - 2020-02-28 16:15 +0000
Re: After doing a lot of the problems on codingbat.com James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-02-28 10:37 -0800
Re: After doing a lot of the problems on codingbat.com Bart <bc@freeuk.com> - 2020-02-28 19:22 +0000
Re: After doing a lot of the problems on codingbat.com David Brown <david.brown@hesbynett.no> - 2020-03-01 14:54 +0100
Re: After doing a lot of the problems on codingbat.com Bart <bc@freeuk.com> - 2020-03-01 15:36 +0000
Re: After doing a lot of the problems on codingbat.com David Brown <david.brown@hesbynett.no> - 2020-03-01 17:08 +0100
Re: After doing a lot of the problems on codingbat.com Richard Damon <Richard@Damon-Family.org> - 2020-02-27 21:57 -0500
Really??? (Was: After doing a lot of the problems on codingbat.com) gazelle@shell.xmission.com (Kenny McCormack) - 2020-02-28 13:06 +0000
Re: Really??? (Was: After doing a lot of the problems on codingbat.com) chad <cdalten@gmail.com> - 2020-02-28 05:47 -0800
Re: Really??? (Was: After doing a lot of the problems on codingbat.com) James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-02-28 05:59 -0800
Re: After doing a lot of the problems on codingbat.com Bart <bc@freeuk.com> - 2020-02-28 14:04 +0000
Re: After doing a lot of the problems on codingbat.com Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-02-28 17:50 +0000
Re: After doing a lot of the problems on codingbat.com Anton Shepelev <anton.txt@g{oogle}mail.com> - 2020-02-28 20:59 +0300
Re: After doing a lot of the problems on codingbat.com Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-02-28 22:37 +0000
Re: After doing a lot of the problems on codingbat.com Bart <bc@freeuk.com> - 2020-02-29 00:17 +0000
Re: After doing a lot of the problems on codingbat.com Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-02-29 01:01 +0000
Re: After doing a lot of the problems on codingbat.com Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-04-02 19:22 -0700
Re: After doing a lot of the problems on codingbat.com Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2020-02-27 14:52 -0500
Re: After doing a lot of the problems on codingbat.com Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-02-27 20:42 +0000
Re: After doing a lot of the problems on codingbat.com David Brown <david.brown@hesbynett.no> - 2020-02-27 22:59 +0100
Re: After doing a lot of the problems on codingbat.com Bart <bc@freeuk.com> - 2020-02-27 20:48 +0000
Re: After doing a lot of the problems on codingbat.com Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-03-27 20:06 -0700
Re: After doing a lot of the problems on codingbat.com chad <cdalten@gmail.com> - 2020-02-27 15:28 -0800
Page 1 of 2 [1] 2 Next page →
| From | chad <cdalten@gmail.com> |
|---|---|
| Date | 2020-02-25 06:55 -0800 |
| Subject | After doing a lot of the problems on codingbat.com |
| Message-ID | <2f146b5c-e025-46ef-af7b-7c328c9f4206@googlegroups.com> |
I've come to this horrible realization that I don't understand a for loop as well as what I thought I did. You all might think this is funny and roll your eyes back. But it's kind of NOT funny when I think I have the solution to a coding problem on that site, only to find out that it fails half the pathological edge cases. With that, I need to accelerate my change in career path from programmer to freeloader.
[toc] | [next] | [standalone]
| From | Anton Shepelev <anton.txt@g{oogle}mail.com> |
|---|---|
| Date | 2020-02-27 20:02 +0300 |
| Message-ID | <20200227200243.157a5e51fe7577f22aa37378@g{oogle}mail.com> |
| In reply to | #150237 |
chad:
> I've come to this horrible realization that I don't
> understand a for loop as well as what I thought I did.
Just don't abuse the for loop, cramping all kinds of
unrelated code into its control expressions. Always use\
it as a loop with a counter:
int i;
/* ... */
for( i = 0; i < n; i += 1 )
{
/* code here that reads but does not modify i */
}
--
() ascii ribbon campaign - against html e-mail
/\ http://preview.tinyurl.com/qcy6mjc [archived]
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2020-02-27 11:41 -0800 |
| Message-ID | <b0f58500-b77b-4bf1-b390-ac69a3e3cce0@googlegroups.com> |
| In reply to | #150303 |
On Thursday, February 27, 2020 at 12:02:53 PM UTC-5, Anton Shepelev wrote: > chad: > > > I've come to this horrible realization that I don't > > understand a for loop as well as what I thought I did. > > Just don't abuse the for loop, cramping all kinds of > unrelated code into its control expressions. ... I'm in full agreement with that. > ... Always use\ > it as a loop with a counter: But I can't agree that there's anything wrong with using any of the following constructs: for(unsigned mask = 0x8000; mask; mask >>=1) for(Node* node=head; node; node = node->next) The first three user-controlled parts of a for-statement should be reserved for loop-control, but there's many different ways to handle loop control.
[toc] | [prev] | [next] | [standalone]
| From | Joe Pfeiffer <pfeiffer@cs.nmsu.edu> |
|---|---|
| Date | 2020-02-27 14:48 -0700 |
| Message-ID | <1bd09zpur1.fsf@pfeifferfamily.net> |
| In reply to | #150305 |
James Kuyper <jameskuyper@alumni.caltech.edu> writes: > On Thursday, February 27, 2020 at 12:02:53 PM UTC-5, Anton Shepelev wrote: >> chad: >> >> > I've come to this horrible realization that I don't >> > understand a for loop as well as what I thought I did. >> >> Just don't abuse the for loop, cramping all kinds of >> unrelated code into its control expressions. ... > > I'm in full agreement with that. > >> ... Always use\ >> it as a loop with a counter: > > But I can't agree that there's anything wrong with using any of the > following constructs: > > for(unsigned mask = 0x8000; mask; mask >>=1) > > for(Node* node=head; node; node = node->next) > > The first three user-controlled parts of a for-statement should be > reserved for loop-control, but there's many different ways to handle > loop control. I'd agree with "always use it as an iterator" (and your examples are all doing so).
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2020-02-27 23:17 +0000 |
| Message-ID | <66Y5G.466396$Uz.23163@fx32.am4> |
| In reply to | #150305 |
On 27/02/2020 19:41, James Kuyper wrote:
> On Thursday, February 27, 2020 at 12:02:53 PM UTC-5, Anton Shepelev wrote:
>> chad:
>>
>>> I've come to this horrible realization that I don't
>>> understand a for loop as well as what I thought I did.
>>
>> Just don't abuse the for loop, cramping all kinds of
>> unrelated code into its control expressions. ...
>
> I'm in full agreement with that.
>
>> ... Always use\
>> it as a loop with a counter:
>
> But I can't agree that there's anything wrong with using any of the
> following constructs:
>
> for(unsigned mask = 0x8000; mask; mask >>=1)
>
> for(Node* node=head; node; node = node->next)
>
> The first three user-controlled parts of a for-statement should be
> reserved for loop-control, but there's many different ways to handle
> loop control.
>
unsigned mask = 0x8000h
while (mask) {
body;
mask >>= 1;
}
Node * node = head;
while (node) {
body;
node = node->next;
}
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2020-02-27 16:40 -0800 |
| Message-ID | <6e7cb40b-afaa-4c54-b445-6cbf407c0697@googlegroups.com> |
| In reply to | #150314 |
On Thursday, February 27, 2020 at 6:17:31 PM UTC-5, Bart wrote:
> On 27/02/2020 19:41, James Kuyper wrote:
...
> > But I can't agree that there's anything wrong with using any of the
> > following constructs:
> >
> > for(unsigned mask = 0x8000; mask; mask >>=1)
> >
> > for(Node* node=head; node; node = node->next)
> >
> > The first three user-controlled parts of a for-statement should be
> > reserved for loop-control, but there's many different ways to handle
> > loop control.
> >
>
> unsigned mask = 0x8000h
> while (mask) {
> body;
> mask >>= 1;
> }
>
> Node * node = head;
> while (node) {
> body;
> node = node->next;
> }
Good, so you know how for loops are related to while loops. Now, did you
find the while loops any easier to understand than the corresponding for
loops? Every feature in one of those for loops that might make it hard to
understand is equally present in the corresponding while loop, providing
an equal opportunity for confusion. The only difference is that the three
different parts of the loop controls are scattered over three different
locationsin the while loop versions, making them marginally harder to connect
with each other - which is precisely why a construct was invented to package
them together.
Frankly, the only reason I can imagine for finding the for() versions
more confusing is a mindset that insists on interpreting them as
equivalent to Fortan FOR loops, with unnecessary extra capabilities. If
you instead think of them as a convenient repacking of common patterns in
while loops, they are much easier to understand.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2020-02-28 01:08 +0000 |
| Message-ID | <aKZ5G.1376648$GFe.757153@fx12.am4> |
| In reply to | #150319 |
On 28/02/2020 00:40, James Kuyper wrote:
> On Thursday, February 27, 2020 at 6:17:31 PM UTC-5, Bart wrote:
>> On 27/02/2020 19:41, James Kuyper wrote:
> ...
>>> But I can't agree that there's anything wrong with using any of the
>>> following constructs:
>>>
>>> for(unsigned mask = 0x8000; mask; mask >>=1)
>>>
>>> for(Node* node=head; node; node = node->next)
>>>
>>> The first three user-controlled parts of a for-statement should be
>>> reserved for loop-control, but there's many different ways to handle
>>> loop control.
>>>
>>
>> unsigned mask = 0x8000h
>> while (mask) {
>> body;
>> mask >>= 1;
>> }
>>
>> Node * node = head;
>> while (node) {
>> body;
>> node = node->next;
>> }
>
> Good, so you know how for loops are related to while loops. Now, did you
> find the while loops any easier to understand than the corresponding for
> loops? Every feature in one of those for loops that might make it hard to
> understand is equally present in the corresponding while loop, providing
> an equal opportunity for confusion. The only difference is that the three
> different parts of the loop controls are scattered over three different
> locationsin the while loop versions, making them marginally harder to connect
> with each other - which is precisely why a construct was invented to package
> them together.
>
> Frankly, the only reason I can imagine for finding the for() versions
> more confusing is a mindset that insists on interpreting them as
> equivalent to Fortan FOR loops, with unnecessary extra capabilities.
Most of them will be. But enough won't be so that means having to pause
and analyse each one, even ones like 'for (int i=0; i<N; ++j)' which
look like simple iteration at first but with minor deviances.
Here are some wonderful examples from sqlite3:
for (;*zTok;zTok++){
for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff);
iCol>=0;
pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
){
for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){
for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
for(i=0, n=1; zFmt[i]; i++, n++){
for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
for(i=*pRoot; i>0; i=iNext){
for(i=mem3.aiHash[hash]; i>0; i=mem3.aPool[i].u.list.next){
for(iFullSz=mem5.szAtom,iLogsize=0; iFullSz<nByte;
iFullSz*=2,iLogsize++){}
for(iLog=0; (iLog<(int)((sizeof(int)*8)-1)) && (1<<iLog)<iValue;
iLog++);
for(i=0; i<=LOGMAX && i+nMinLog<32; i++){
for(n=0, j=mem5.aiFreelist[i]; j>=0; j = MEM5LINK(j)->next, n++){}
for(; (c=(*fmt))!=0; ++fmt){
With this last, is there any reason why this shouldn't have been a
simple while loop? If not, then why does C even bother having while(c){}
when someone can just write for(;c;){}?
For many of these, you really have to hunt to even find the condition,
or determine which one is the loop variable, if any.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2020-02-28 01:37 -0800 |
| Message-ID | <871rqft5ml.fsf@nosuchdomain.example.com> |
| In reply to | #150320 |
Bart <bc@freeuk.com> writes:
> On 28/02/2020 00:40, James Kuyper wrote:
[...]
>> Frankly, the only reason I can imagine for finding the for() versions
>> more confusing is a mindset that insists on interpreting them as
>> equivalent to Fortan FOR loops, with unnecessary extra capabilities.
>
> Most of them will be. But enough won't be so that means having to
> pause and analyse each one, even ones like 'for (int i=0; i<N; ++j)'
> which look like simple iteration at first but with minor deviances.
>
> Here are some wonderful examples from sqlite3:
>
[snip]
> for(; (c=(*fmt))!=0; ++fmt){
>
> With this last, is there any reason why this shouldn't have been a
> simple while loop? If not, then why does C even bother having
> while(c){} when someone can just write for(;c;){}?
I have no problem with that for loop. I'm aware that you do, and I'm
not interested in changing your mind. I'm just making you aware that
some of us find the "for" version readable.
Something like
for (;c;){}
should almost certainly be a while loop, but in the above example
it's handy to put the ++fmt at the top of the loop rather than
burying it at the bottom.
(It would have been more for-like if fmt were initialized in the loop.
Without context, I can't guess why that wasn't done.)
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2020-02-28 06:21 -0800 |
| Message-ID | <7d6d4d11-8051-4d35-b3ec-8fd4cda1ce93@googlegroups.com> |
| In reply to | #150320 |
On Thursday, February 27, 2020 at 8:08:31 PM UTC-5, Bart wrote:
> On 28/02/2020 00:40, James Kuyper wrote:
...
> > Good, so you know how for loops are related to while loops. Now, did you
> > find the while loops any easier to understand than the corresponding for
> > loops? Every feature in one of those for loops that might make it hard to
> > understand is equally present in the corresponding while loop, providing
> > an equal opportunity for confusion. The only difference is that the three
> > different parts of the loop controls are scattered over three different
> > locations in the while loop versions, making them marginally harder to connect
> > with each other - which is precisely why a construct was invented to package
> > them together.
> >
> > Frankly, the only reason I can imagine for finding the for() versions
> > more confusing is a mindset that insists on interpreting them as
> > equivalent to Fortan FOR loops, with unnecessary extra capabilities.
Correction: Fortran DO loops.
> Most of them will be. But enough won't be so that means having to pause
> and analyse each one, even ones like 'for (int i=0; i<N; ++j)' which
> look like simple iteration at first but with minor deviances.
That one would violate my guidelines for for-statements: the
first three user-provided sections of a for-statement should be
things that work together to provide the loop control. Since j
plays no direct role in the loop condition, it's increment should
have been moved to the body of the loop. You can misuse any
feature of any language; bad use of for statements shouldn't be
considered a problem with for statements, but a problem with the
author of such code.
> Here are some wonderful examples from sqlite3:
>
> for (;*zTok;zTok++){
>
> for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff);
> iCol>=0;
> pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
> ){
>
> for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){
>
> for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
>
> for(i=0, n=1; zFmt[i]; i++, n++){
>
> for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
>
> for(i=*pRoot; i>0; i=iNext){
>
> for(i=mem3.aiHash[hash]; i>0; i=mem3.aPool[i].u.list.next){
>
> for(iFullSz=mem5.szAtom,iLogsize=0; iFullSz<nByte;
> iFullSz*=2,iLogsize++){}
>
> for(iLog=0; (iLog<(int)((sizeof(int)*8)-1)) && (1<<iLog)<iValue;
> iLog++);
>
> for(i=0; i<=LOGMAX && i+nMinLog<32; i++){
>
> for(n=0, j=mem5.aiFreelist[i]; j>=0; j = MEM5LINK(j)->next, n++){}
>
> for(; (c=(*fmt))!=0; ++fmt){
And can you identify even a single one of those statements that
would have been less confusing to you if written using a while
loop rather than a for loop?
> With this last, is there any reason why this shouldn't have been a
> simple while loop? If not, then why does C even bother having while(c){}
> when someone can just write for(;c;){}?
I would have written that as for(; c=*fmt; ++fmt), which is a
matter of taste, but I don't see anything else wrong with it.
> For many of these, you really have to hunt to even find the condition,
You find it difficult to search for ';' tokens? The condition is
the thing between the first two ';' tokens following the "for".
It seems pretty simple and trivial to me.
> or determine which one is the loop variable, if any.
There need not be a loop variable, or there might be more than
one, in which case finding "the" loop variable runs into obvious
problems; problems that would still exist if you used a while()
loop rather than a for loop.
However, I had no trouble identifying the loop variables in any
of the examples you gave. They are zTok, iCol, p, n, i, pVfs, i,
i, iFullSz, iLog, i, j, and fmt, in that order. Which ones did
you have trouble identifying, and why?
trouble identifying them?
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2020-02-28 16:15 +0000 |
| Message-ID | <l0b6G.330443$BA5.123969@fx21.am4> |
| In reply to | #150335 |
On 28/02/2020 14:21, James Kuyper wrote:
> On Thursday, February 27, 2020 at 8:08:31 PM UTC-5, Bart wrote:
>> On 28/02/2020 00:40, James Kuyper wrote:
> ...
>>> Good, so you know how for loops are related to while loops. Now, did you
>>> find the while loops any easier to understand than the corresponding for
>>> loops? Every feature in one of those for loops that might make it hard to
>>> understand is equally present in the corresponding while loop, providing
>>> an equal opportunity for confusion. The only difference is that the three
>>> different parts of the loop controls are scattered over three different
>>> locations in the while loop versions, making them marginally harder to connect
>>> with each other - which is precisely why a construct was invented to package
>>> them together.
>>>
>>> Frankly, the only reason I can imagine for finding the for() versions
>>> more confusing is a mindset that insists on interpreting them as
>>> equivalent to Fortan FOR loops, with unnecessary extra capabilities.
>
> Correction: Fortran DO loops.
>
>> Most of them will be. But enough won't be so that means having to pause
>> and analyse each one, even ones like 'for (int i=0; i<N; ++j)' which
>> look like simple iteration at first but with minor deviances.
>
> That one would violate my guidelines for for-statements: the
> first three user-provided sections of a for-statement should be
> things that work together to provide the loop control. Since j
> plays no direct role in the loop condition, it's increment should
> have been moved to the body of the loop. You can misuse any
> feature of any language; bad use of for statements shouldn't be
> considered a problem with for statements, but a problem with the
> author of such code.
>
>> Here are some wonderful examples from sqlite3:
>>
>> for (;*zTok;zTok++){
>>
>> for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff);
>> iCol>=0;
>> pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
>> ){
>>
>> for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){
>>
>> for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
>>
>> for(i=0, n=1; zFmt[i]; i++, n++){
>>
>> for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
>>
>> for(i=*pRoot; i>0; i=iNext){
>>
>> for(i=mem3.aiHash[hash]; i>0; i=mem3.aPool[i].u.list.next){
>>
>> for(iFullSz=mem5.szAtom,iLogsize=0; iFullSz<nByte;
>> iFullSz*=2,iLogsize++){}
>>
>> for(iLog=0; (iLog<(int)((sizeof(int)*8)-1)) && (1<<iLog)<iValue;
>> iLog++);
>>
>> for(i=0; i<=LOGMAX && i+nMinLog<32; i++){
>>
>> for(n=0, j=mem5.aiFreelist[i]; j>=0; j = MEM5LINK(j)->next, n++){}
>>
>> for(; (c=(*fmt))!=0; ++fmt){
>
> And can you identify even a single one of those statements that
> would have been less confusing to you if written using a while
> loop rather than a for loop?
Such capabilities *encourage* people to write complicated loops and to
try and cram too much in one place.
But yes, using coding guidelines where a for-loop is ONLY used to
iterate one loop variable over a range, then you can tell instantly that
that is what it does. In compiling those examples, I had to stop and
analyse each one, and chose the ones that weren't simple iterations.
Let's try one however:
for(n=0, j=mem5.aiFreelist[i]; j>=0; j = MEM5LINK(j)->next, n++){}
I need to disentagle this to see what's what; this is not a candidate
for a simple for (n increments simply, but the loop condition depends on
j which doesn't). It might become:
n = 0;
j = mem5.aiFreelist[i];
while (j>=0) {
j = MEM5LINK(j)->next;
++n;
}
Note the empty body on original; everything it does is inside the
header. Now it is a little clearer that it traverses some sort of linked
list, counting the nodes encountered in n.
>> With this last, is there any reason why this shouldn't have been a
>> simple while loop? If not, then why does C even bother having while(c){}
>> when someone can just write for(;c;){}?
>
> I would have written that as for(; c=*fmt; ++fmt), which is a
> matter of taste, but I don't see anything else wrong with it.
>
>> For many of these, you really have to hunt to even find the condition,
>
> You find it difficult to search for ';' tokens?
Given unlimited time then of course you can spend enough time analysing
it. But you can't see it at a glance. The example I expanded included
two commas and a dot among the two semicolons.
However, the source file it came from had 220,000 lines of this stuff.
The condition is
> the thing between the first two ';' tokens following the "for".
> It seems pretty simple and trivial to me.
How complicated does a for header need to be before you will admit it
can take a while to locate those semicolons? Even if you spot one
immediately, is that the first or second semicolon? You have to then
scan both ways.
This is different from semicolons used for normal statements where they
usually at the end of a line.
>> or determine which one is the loop variable, if any.
>
> There need not be a loop variable, or there might be more than
> one, in which case finding "the" loop variable runs into obvious
> problems; problems that would still exist if you used a while()
> loop rather than a for loop.
>
> However, I had no trouble identifying the loop variables in any
> of the examples you gave. They are zTok, iCol, p, n, i, pVfs, i,
> i, iFullSz, iLog, i, j, and fmt, in that order. Which ones did
> you have trouble identifying, and why?
> trouble identifying them?
As I said, given enough time, you can do it. That's also the case if all
identifiers were obsfuscated, and all unnecessary white space removed so
that a source file is one long line.
But the point here is writing clear code that you can grok at a glance.
Note that MISRA guidelines from 2004 (first free version I found)
include the following rules:
Rule 13.5 (required):The three expressions of a for statement shall be
concerned only with loop control.The three expressions of a for
statement shall be used only for these purposes:
First expression: Initialising the loop counter (i in the following
example [not shown])
Second expressin: Shall include testing the loop counter (i), and
optionally other loop control variables (flag)
Third expression: Increment or decrement of the loop counter (i)
The following options are allowed:
(a) All three expressions shall be present;
(b) The second and third expressions shall be present with prior
initialisation of the loop counter;
(c) All three expressions shall be empty for a deliberate infinite loop.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2020-02-28 10:37 -0800 |
| Message-ID | <a9b6846e-92b9-4702-901d-b509cd2655f6@googlegroups.com> |
| In reply to | #150336 |
On Friday, February 28, 2020 at 11:15:23 AM UTC-5, Bart wrote:
> On 28/02/2020 14:21, James Kuyper wrote:
...
> > And can you identify even a single one of those statements that
> > would have been less confusing to you if written using a while
> > loop rather than a for loop?
>
> Such capabilities *encourage* people to write complicated loops and to
> try and cram too much in one place.
If those capabilities weren't available, I'd have written the
corresponding while loop, not a for loop fitting the requirements you
favor.
That's why I've repeatedly asked you to compare a complicated for-loop
with a complicated while loop, comparing it with a simple for loop is
not a relevant comparison, because a simple for loop won't do the job.
> But yes, using coding guidelines where a for-loop is ONLY used to
> iterate one loop variable over a range, then you can tell instantly that
> that is what it does.
What good would that do? Under such guidelines, I wouldn't be writing
for loops that met those guidelines, not for the complicated cases that
bother you so much. I'd have to skip the convenience of for loop, and
instead settle for the slightly more obfuscated equivalent while loop.
> ... In compiling those examples, I had to stop and
> analyse each one, and chose the ones that weren't simple iterations.
>
> Let's try one however:
>
> for(n=0, j=mem5.aiFreelist[i]; j>=0; j = MEM5LINK(j)->next, n++){}
That's poorly written by my standards. Since n doesn't play any direct
role in the loop condition, n=0 should have been moved before the loop,
and n++ should have been moved into the loop body. Would you have
considered that more readable?
> I need to disentagle this to see what's what; this is not a candidate
> for a simple for (n increments simply, but the loop condition depends on
> j which doesn't). It might become:
>
> n = 0;
> j = mem5.aiFreelist[i];
>
> while (j>=0) {
> j = MEM5LINK(j)->next;
> ++n;
> }
>
> Note the empty body on original; everything it does is inside the
> header. Now it is a little clearer that it traverses some sort of linked
> list, counting the nodes encountered in n.
It looks no less complicated to me in this form than in the other.
...
> >> For many of these, you really have to hunt to even find the condition,
> >
> > You find it difficult to search for ';' tokens?
>
> Given unlimited time then of course you can spend enough time analysing
> it. But you can't see it at a glance.
I can't? Well, I did. It took me negligible time to identify the
condition in each of those statements; so negligible that I can't figure
out how to measure it.
...
> The condition is
> > the thing between the first two ';' tokens following the "for".
> > It seems pretty simple and trivial to me.
>
> How complicated does a for header need to be before you will admit it
> can take a while to locate those semicolons? ...
It would have to be more than three lines long, which is pretty rare in
my experience. Most of the multi-line for-headers that I've seen have
put the semi-colons at the end of a line, making it trivial to find
them, which is why that's common practice. So it would have to be more
than three lines long AND badly formatted.
Shorter for-headers should have at least a space after each semicolon -
the most confusing of the examples you cited violate that style
guideline.
> ... Even if you spot one
> immediately, is that the first or second semicolon? You have to then
> scan both ways.
Really? You find them so difficult to locate that you have trouble
counting all the LONG way from 1 to 2 as you're scanning along? Really?
Is the prescription on your glasses/contacts up-to-date?
...
> But the point here is writing clear code that you can grok at a glance.
I can grok most of the examples you listed with no trouble at all, and
putting the third part of the for statement together with the first two
makes it much easier to understand, in my experience.
> Note that MISRA guidelines from 2004 (first free version I found)
Most MISRA guidelines I've seen are ill-conceived. This might be a
selection effect - the ill-conceived ones are the ones most likely to be
discussed (oddly enough, this seems to include people who don't consider
them ill-conceived, such as yourself). That's probably because MISRA
supporters are more likely to discuss guidelines that opponents have
criticized.
> include the following rules:
>
>
> Rule 13.5 (required):The three expressions of a for statement shall be
> concerned only with loop control. ...
That I can perfectly agree with.
> ... The three expressions of a for
> statement shall be used only for these purposes:
>
> First expression: Initialising the loop counter (i in the following
> example [not shown])
I'd change that to "loop variable(s) (if any)".
> Second expressin: Shall include testing the loop counter (i), and
> optionally other loop control variables (flag)
If "test" is understood to include any condition containing the loop
variable(s), that's also acceptable.
> Third expression: Increment or decrement of the loop counter (i)
That's the ill-concieved part, which rejects every reason why for()
loops were defined in the C the way that they are.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2020-02-28 19:22 +0000 |
| Message-ID | <NLd6G.393808$co3.207861@fx11.am4> |
| In reply to | #150340 |
On 28/02/2020 18:37, James Kuyper wrote:
> On Friday, February 28, 2020 at 11:15:23 AM UTC-5, Bart wrote:
>> Let's try one however:
>>
>> for(n=0, j=mem5.aiFreelist[i]; j>=0; j = MEM5LINK(j)->next, n++){}
>
> That's poorly written by my standards. Since n doesn't play any direct
> role in the loop condition, n=0 should have been moved before the loop,
> and n++ should have been moved into the loop body. Would you have
> considered that more readable?
A little, as it would have slightly simplified the loop-header. But this
example would still have an unusually complex initialisation, and an
unusually complex increment.
As it is, someone seeing the n=0 at the start, and the n++ at the end,
might jump to conclusion that it's an interative loop.
>> I need to disentagle this to see what's what; this is not a candidate
>> for a simple for (n increments simply, but the loop condition depends on
>> j which doesn't). It might become:
>>
>> n = 0;
>> j = mem5.aiFreelist[i];
>>
>> while (j>=0) {
>> j = MEM5LINK(j)->next;
>> ++n;
>> }
>>
>> Note the empty body on original; everything it does is inside the
>> header. Now it is a little clearer that it traverses some sort of linked
>> list, counting the nodes encountered in n.
>
>
> It looks no less complicated to me in this form than in the other.
The original consisted on 5 statements really, but crammed onto one
line; mine has one statement per line with a clearer execution path.
It's also easier to comment-out lines, or add logging or debug code
either before or after the 'increment'.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2020-03-01 14:54 +0100 |
| Message-ID | <r3geqc$20e$1@dont-email.me> |
| In reply to | #150336 |
On 28/02/2020 17:15, Bart wrote: > Note that MISRA guidelines from 2004 (first free version I found) > include the following rules: > Important nitpick - you mean that was the first unlicensed copy you found on the net. MISRA is not free - you have to pay for it, in /every/ case. It costs £10.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2020-03-01 15:36 +0000 |
| Message-ID | <EDQ6G.361152$QS6.129687@fx02.am4> |
| In reply to | #150355 |
On 01/03/2020 13:54, David Brown wrote: > On 28/02/2020 17:15, Bart wrote: > >> Note that MISRA guidelines from 2004 (first free version I found) >> include the following rules: >> > > Important nitpick - you mean that was the first unlicensed copy you > found on the net. MISRA is not free - you have to pay for it, in > /every/ case. It costs £10. Funny sort of pricing. For people like me £10 is a significant amount to pay just to extract a quote for usenet (ie. == ten loaves of bread). For the corporations that it seems aimed at, it is totally insignificant. It should cost more for commercial use and be free for non-commercial/educational use. If anyone's interested, I can draw up my own guidelines for writing C - for free.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2020-03-01 17:08 +0100 |
| Message-ID | <r3gmln$nv$1@dont-email.me> |
| In reply to | #150357 |
On 01/03/2020 16:36, Bart wrote: > On 01/03/2020 13:54, David Brown wrote: >> On 28/02/2020 17:15, Bart wrote: >> >>> Note that MISRA guidelines from 2004 (first free version I found) >>> include the following rules: >>> >> >> Important nitpick - you mean that was the first unlicensed copy you >> found on the net. MISRA is not free - you have to pay for it, in >> /every/ case. It costs £10. > > Funny sort of pricing. For people like me £10 is a significant amount to > pay just to extract a quote for usenet (ie. == ten loaves of bread). For > the corporations that it seems aimed at, it is totally insignificant. > > It should cost more for commercial use and be free for > non-commercial/educational use. > The effect of their pricing is that any commercial entity that wants their standard, has it. Any commercial (including zero cost) embedded compiler and tools can support MISRA rule checking as part of their static analysis. But open source compilers and tools cannot (or at least, they can't do so easily). I've had dealings with at least one person involved in MISRA in the past, and passed on that person's attitudes towards open source tools, it would not surprise me if this effect is precisely the reason for their pricing. > If anyone's interested, I can draw up my own guidelines for writing C - > for free. You forgot the smiley!
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2020-02-27 21:57 -0500 |
| Message-ID | <ok%5G.264259$ss1.247832@fx42.iad> |
| In reply to | #150319 |
On 2/27/20 7:40 PM, James Kuyper wrote:
> On Thursday, February 27, 2020 at 6:17:31 PM UTC-5, Bart wrote:
>> On 27/02/2020 19:41, James Kuyper wrote:
> ...
>>> But I can't agree that there's anything wrong with using any of the
>>> following constructs:
>>>
>>> for(unsigned mask = 0x8000; mask; mask >>=1)
>>>
>>> for(Node* node=head; node; node = node->next)
>>>
>>> The first three user-controlled parts of a for-statement should be
>>> reserved for loop-control, but there's many different ways to handle
>>> loop control.
>>>
>>
>> unsigned mask = 0x8000h
>> while (mask) {
>> body;
>> mask >>= 1;
>> }
>>
>> Node * node = head;
>> while (node) {
>> body;
>> node = node->next;
>> }
>
> Good, so you know how for loops are related to while loops. Now, did you
> find the while loops any easier to understand than the corresponding for
> loops? Every feature in one of those for loops that might make it hard to
> understand is equally present in the corresponding while loop, providing
> an equal opportunity for confusion. The only difference is that the three
> different parts of the loop controls are scattered over three different
> locationsin the while loop versions, making them marginally harder to connect
> with each other - which is precisely why a construct was invented to package
> them together.
>
> Frankly, the only reason I can imagine for finding the for() versions
> more confusing is a mindset that insists on interpreting them as
> equivalent to Fortan FOR loops, with unnecessary extra capabilities. If
> you instead think of them as a convenient repacking of common patterns in
> while loops, they are much easier to understand.
>
One important difference between a for loop and a while loop with the
iteration at the end of the loop is it behavior when the body of the
loop has a continue statement. The for loop will run the iteration
clause, while the while loop, since it doesn't have a real spot for the
iteration clause, just repeats the loop, unless you convert the continue
statement into a goto.
In my mind, that make the for loop better for loops that really are a
natural iteration.
[toc] | [prev] | [next] | [standalone]
| From | gazelle@shell.xmission.com (Kenny McCormack) |
|---|---|
| Date | 2020-02-28 13:06 +0000 |
| Subject | Really??? (Was: After doing a lot of the problems on codingbat.com) |
| Message-ID | <r3b37u$v52$1@news.xmission.com> |
| In reply to | #150319 |
In article <6e7cb40b-afaa-4c54-b445-6cbf407c0697@googlegroups.com>, James Kuyper <jameskuyper@alumni.caltech.edu> wrote: ... >Frankly, the only reason I can imagine for finding the for() versions >more confusing is a mindset that insists on interpreting them as >equivalent to Fortan FOR loops, with unnecessary extra capabilities. If >you instead think of them as a convenient repacking of common patterns in >while loops, they are much easier to understand. FORTRAN has "FOR" loops? -- The randomly chosen signature file that would have appeared here is more than 4 lines long. As such, it violates one or more Usenet RFCs. In order to remain in compliance with said RFCs, the actual sig can be found at the following URL: http://user.xmission.com/~gazelle/Sigs/DanQuayle
[toc] | [prev] | [next] | [standalone]
| From | chad <cdalten@gmail.com> |
|---|---|
| Date | 2020-02-28 05:47 -0800 |
| Subject | Re: Really??? (Was: After doing a lot of the problems on codingbat.com) |
| Message-ID | <7a75bf85-3143-42da-b49c-3ff5b31b753f@googlegroups.com> |
| In reply to | #150331 |
On Friday, February 28, 2020 at 5:06:15 AM UTC-8, Kenny McCormack wrote: > In article <6e7cb40b-afaa-4c54-b445-6cbf407c0697@googlegroups.com>, > James Kuyper <jameskuyper@alumni.caltech.edu> wrote: > ... > >Frankly, the only reason I can imagine for finding the for() versions > >more confusing is a mindset that insists on interpreting them as > >equivalent to Fortan FOR loops, with unnecessary extra capabilities. If > >you instead think of them as a convenient repacking of common patterns in > >while loops, they are much easier to understand. > > FORTRAN has "FOR" loops? > Maybe it got implemented on Rick's CAlive compiler?
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2020-02-28 05:59 -0800 |
| Subject | Re: Really??? (Was: After doing a lot of the problems on codingbat.com) |
| Message-ID | <e7a9d6a5-c18b-4434-928d-210231d6e3ed@googlegroups.com> |
| In reply to | #150331 |
On Friday, February 28, 2020 at 8:06:15 AM UTC-5, Kenny McCormack wrote: > In article <6e7cb40b-afaa-4c54-b445-6cbf407c0697@googlegroups.com>, > James Kuyper <jameskuyper@alumni.caltech.edu> wrote: > ... > >Frankly, the only reason I can imagine for finding the for() versions > >more confusing is a mindset that insists on interpreting them as > >equivalent to Fortan FOR loops, with unnecessary extra capabilities. If > >you instead think of them as a convenient repacking of common patterns in > >while loops, they are much easier to understand. > > FORTRAN has "FOR" loops? Sorry: DO loops. It's been a LONG time since I wrote any Fortran.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2020-02-28 14:04 +0000 |
| Message-ID | <T596G.615708$cW.132364@fx16.am4> |
| In reply to | #150319 |
On 28/02/2020 00:40, James Kuyper wrote:
> On Thursday, February 27, 2020 at 6:17:31 PM UTC-5, Bart wrote:
>> unsigned mask = 0x8000h
>> while (mask) {
>> body;
>> mask >>= 1;
>> }
>>
>> Node * node = head;
>> while (node) {
>> body;
>> node = node->next;
>> }
> Frankly, the only reason I can imagine for finding the for() versions
> more confusing is a mindset that insists on interpreting them as
> equivalent to Fortan FOR loops, with unnecessary extra capabilities. If
> you instead think of them as a convenient repacking of common patterns in
> while loops, they are much easier to understand.
Fortran loops are a good example. They are necessarily limited in what
they do, and that makes it very easy to reason about compared with the
myriad variations that can be introduced with C's for as I showed in my
other post.
Actually, modern Fortran doesn't seem to have needed to adopt anything
like C's 'for' either; it has DO, and it has DO WHILE.
I did try to duplicate it once (with an eye to easily translate C code),
but it used WHILE to make it clear it wasn't FOR:
while i=0, i<N, ++i do ...
But it was never used and quickly dropped. I just didn't like combining
statements like this, which inevitably end up on the same line, and
which can be out-of-order (deferred execution).
(Write such a loop on paper, and then with a red pen show the flow of
control; it will be a mess, with three entry points into the loop header.)
Maybe there is an advantage to encapsulating the increment part (to
solve the issues with 'continue' for example), but in a true 'for' loop,
there is NO increment part; the idea is that the compiler fills in those
details!
(If I wanted to isolate the incrementing part of a while loop like the
above, there is a way but it is not tidy [not C syntax]:
i := 0
while i<N do
to 1 do
body...
od
++i
od
Here at least the increment is in the right place.
There can be an advantage also to encapsulating the initialisation code
in a while loop, but not in C. I could use that because I have a
'restart' loop control, which is not available in C. But even that is
possible with an extra outer loop.
Meanwhile many of my loops now look like this: 'for i in A do'; where is
the initialisation, where is the condition for end of loop, and where is
the increment?)
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web