From: Nathan on
On Apr 28, 1:16 am, Juha Nieminen <nos...(a)thanks.invalid> wrote:
> In comp.lang.c++ Richard Heathfield <r...(a)see.sig.invalid> wrote:
>
> > Juha Nieminen wrote:
> >> In comp.lang.c++ Richard Heathfield <r...(a)see.sig.invalid> wrote:
> >>>>   Exactly how do you exit out of a set of nested loops with a "break"?
> >>> I don't. I exit out of a set of nested loops using the conditions in the
> >>> loop controllers.
>
> >>   The idea was to make the code simpler, cleaner and easier to follow, not
> >> more complicated and contrived.
>
> > Yes. That's precisely why I use the conditions in the loop controllers.
>
>   Care to show an actual example of your "simpler, cleaner and easier to
> follow" version of exiting a nested loop by meddling with the loop
> conditions instead of using 'return'? For example, modify the following
> code to conform to your specifications:
>
> Value_t* MyClass::findValue(const Value_t& value)
> {
>     for(size_t xInd = 0; xInd < data.size(); ++xInd)
>         for(size_t yInd = 0; yInd < data[xInd].size(); ++yInd)
>             for(size_t zInd = 0; zInd < data[xInd][yInd].size(); ++zInd)
>             {
>                 if(data[xInd][yInd][zInd] == value)
>                     return &data[xInd][yInd][zInd];
>             }
>
>     return 0;
>
> }

Hi Juha,

I think that you either copied this from a poorly-written beginner C++
book or you failed to understand what the author was attempting to
demonstrate with that kind of code and that you did not 'catch on'
that it is not (in any way) demonstrative of how one walks a series of
sequential cells in the real world.

Why do you insist on writing control structures that serve little
actual purpose? For instance, it should be obvious that you only
require ONE loop and a few conditionals to achieve your desired (or
assumed) goal. E.G...

,---
result = value
xInd = 0
yInd = 0
zInd = 0
while ( data[xInd][yInd][zInd] != value && result != 0)
{
++zInd;
if (( zInd < data[xInd][yInd].size() ) != true ) { zInd = 0; +
+yInd};
if (( yInd < data[xInd].size() ) != true ) { yInd = 0; ++xInd};
if (( xInd < data.size() ) != true ) { result = 0 };
}
return result
`---

Of course, this is a rather useless (maybe even retarded) function to
begin with, because it only tells you IF the 'value' is located
"somewhere" within that array -- it gives you absolutely no indication
of "where" in that array you might be able to access the item which
matches your search criteria.

Please pardon any butchering of C++ syntax in my pseudo snippet above
-- I totally lack any C++ training. But we alt.lang.asm folk *do*
have an inkling of how to actually code our way out of a paper bag...
I do believe.

Nathan.
From: tonydee on
On May 6, 2:36 pm, Nathan <nathancba...(a)gmail.com> wrote:
> On Apr 28, 1:16 am, Juha Nieminen <nos...(a)thanks.invalid> wrote:
> >   Care to show an actual example of your "simpler, cleaner and easier to
> > follow" version of exiting a nested loop by meddling with the loop
> > conditions instead of using 'return'? For example, modify the following
> > code to conform to your specifications:
>
> > Value_t* MyClass::findValue(const Value_t& value)
> > {
> >     for(size_t xInd = 0; xInd < data.size(); ++xInd)
> >         for(size_t yInd = 0; yInd < data[xInd].size(); ++yInd)
> >             for(size_t zInd = 0; zInd < data[xInd][yInd].size(); ++zInd)
> >             {
> >                 if(data[xInd][yInd][zInd] == value)
> >                     return &data[xInd][yInd][zInd];
> >             }
> >     return 0;
> > }
>
> Hi Juha,
>
> I think that you either copied this from a poorly-written beginner C++
> book or you failed to understand what the author was attempting to
> demonstrate with that kind of code and that you did not 'catch on'
> that it is not (in any way) demonstrative of how one walks a series of
> sequential cells in the real world.
>
> Why do you insist on writing control structures that serve little
> actual purpose?  For instance, it should be obvious that you only
> require ONE loop and a few conditionals to achieve your desired (or
> assumed) goal.  E.G...
>
> ,---
> result = value
> xInd = 0
> yInd = 0
> zInd = 0
> while ( data[xInd][yInd][zInd] != value && result != 0)
> {
>     ++zInd;
>     if (( zInd < data[xInd][yInd].size() ) != true ) { zInd = 0; +
> +yInd};
>     if (( yInd < data[xInd].size() ) != true ) { yInd = 0; ++xInd};
>     if (( xInd < data.size() ) != true ) { result = 0 };}
>
> return result
> `---

Juha did ask for something "simpler, cleaner and easier to follow",
which your single loop is not. Perhaps because of that, your code
needlessly compares yInd and xInd to their respective limits on every
iteration, rather than something like...

while ( data[xInd][yInd][zInd] != value && result != 0)
{
if {++zInd == data[xInd][yInd].size()) {
zInd = 0;
if (++yInd == data[xInd].size()) {
yInd = 0;
if (++xInd == data.size())
result = 0;
}
}
...

More importantly, it can dereference index [0] before checking size(),
so produces undefined behaviour. Anyway, IMHO it's far less clear
(=self-evidently correct & efficient as well as maintainable) than
Juha's code.

> Of course, this is a rather useless (maybe even retarded) function to
> begin with, because it only tells you IF the 'value' is located
> "somewhere" within that array -- it gives you absolutely no indication
> of "where" in that array you might be able to access the item which
> matches your search criteria.

You missed that the original function was returning a pointer to the
matching cell, allowing a change to be made at that location,
considerably more useful than the search-term-else-0-sentinel version
you coded.

> Please pardon any butchering of C++ syntax in my pseudo snippet above
> -- I totally lack any C++ training.

Fair enough... no worries.

> But we alt.lang.asm folk *do*
> have an inkling of how to actually code our way out of a paper bag...
> I do believe.
>
> Nathan.

Your central point that a single loop can serve contributes an
interesting alternative, which I'm sure the readers here will
appreciate, if they bother to look past your smug attitude (which is
quite unwarranted given the serious errors in your implementation)....

Cheers,
Tony
From: Nathan on
On May 6, 2:11 am, tonydee <tony_in_da...(a)yahoo.co.uk> wrote:
> On May 6, 2:36 pm, Nathan <nathancba...(a)gmail.com> wrote:
>
>
>
> > On Apr 28, 1:16 am, Juha Nieminen <nos...(a)thanks.invalid> wrote:
> > >   Care to show an actual example of your "simpler, cleaner and easier to
> > > follow" version of exiting a nested loop by meddling with the loop
> > > conditions instead of using 'return'? For example, modify the following
> > > code to conform to your specifications:
>
> > > Value_t* MyClass::findValue(const Value_t& value)
> > > {
> > >     for(size_t xInd = 0; xInd < data.size(); ++xInd)
> > >         for(size_t yInd = 0; yInd < data[xInd].size(); ++yInd)
> > >             for(size_t zInd = 0; zInd < data[xInd][yInd].size(); ++zInd)
> > >             {
> > >                 if(data[xInd][yInd][zInd] == value)
> > >                     return &data[xInd][yInd][zInd];
> > >             }
> > >     return 0;
> > > }
>
> > Hi Juha,
>
> > I think that you either copied this from a poorly-written beginner C++
> > book or you failed to understand what the author was attempting to
> > demonstrate with that kind of code and that you did not 'catch on'
> > that it is not (in any way) demonstrative of how one walks a series of
> > sequential cells in the real world.
>
> > Why do you insist on writing control structures that serve little
> > actual purpose?  For instance, it should be obvious that you only
> > require ONE loop and a few conditionals to achieve your desired (or
> > assumed) goal.  E.G...
>
> > ,---
> > result = value
> > xInd = 0
> > yInd = 0
> > zInd = 0
> > while ( data[xInd][yInd][zInd] != value && result != 0)
> > {
> >     ++zInd;
> >     if (( zInd < data[xInd][yInd].size() ) != true ) { zInd = 0; +
> > +yInd};
> >     if (( yInd < data[xInd].size() ) != true ) { yInd = 0; ++xInd};
> >     if (( xInd < data.size() ) != true ) { result = 0 };}
>
> > return result
> > `---
>
> Juha did ask for something "simpler, cleaner and easier to follow",
> which your single loop is not.

Well, 'y < x' must evaluate as 'true' in order for something to be
classified as simpler. So, because *one loop* < *three loops*, my
version certainly looks simpler. [e.g. less opcodes in the generated
binary ]

> Perhaps because of that, your code
> needlessly compares yInd and xInd to their respective limits on every
> iteration, rather than something like...
>
>   while ( data[xInd][yInd][zInd] != value && result != 0)
>   {
>       if {++zInd == data[xInd][yInd].size()) {
>           zInd = 0;
>           if (++yInd == data[xInd].size()) {
>               yInd = 0;
>               if (++xInd == data.size())
>                   result = 0;
>           }
>       }
>   ...
>
> More importantly, it can dereference index [0] before checking size(),
> so produces undefined behaviour.  Anyway, IMHO it's far less clear
> (=self-evidently correct & efficient as well as maintainable) than
> Juha's code.
>

More maintainable by the original coder... or more maintainable by
someone 'new' to the code??? If this function were many screens in
length, and someone 'new' decides to have it perform an extra task
'just' before returning, wouldn't that person have a "devil of a time"
debugging the program if he were not aware of the hidden alternative
'return' route tucked-away in that nest?

> > Of course, this is a rather useless (maybe even retarded) function to
> > begin with, because it only tells you IF the 'value' is located
> > "somewhere" within that array -- it gives you absolutely no indication
> > of "where" in that array you might be able to access the item which
> > matches your search criteria.
>
> You missed that the original function was returning a pointer to the
> matching cell, allowing a change to be made at that location,
> considerably more useful than the search-term-else-0-sentinel version
> you coded.
>

Ah, the '&' sign, I see it now. I should have "result = &data[xInd]
[yInd][zInd]" in the third IF.

> > Please pardon any butchering of C++ syntax in my pseudo snippet above
> > -- I totally lack any C++ training.
>
> Fair enough... no worries.
>
> > But we alt.lang.asm folk *do*
> > have an inkling of how to actually code our way out of a paper bag...
> > I do believe.
>
> > Nathan.
>
> Your central point that a single loop can serve contributes an
> interesting alternative, which I'm sure the readers here will
> appreciate,

Yes, rather than waste one's time bickering about the various esteemed
implementation alternatives of a particular algo, why not consider an
algo that renders those salient points mute?

> if they bother to look past your smug attitude (which is
> quite unwarranted given the serious errors in your implementation)....
>

This is Usenet, we do not charge for the entertainment value. :)

Nathan.
From: Nathan on
On May 6, 2:11 am, tonydee <tony_in_da...(a)yahoo.co.uk> wrote:
>
> Juha did ask for something "simpler, cleaner and easier to follow",
> which your single loop is not.  Perhaps because of that, your code
> needlessly compares yInd and xInd to their respective limits on every
> iteration, rather than something like...
>
>   while ( data[xInd][yInd][zInd] != value && result != 0)
>   {
>       if {++zInd == data[xInd][yInd].size()) {
>           zInd = 0;
>           if (++yInd == data[xInd].size()) {
>               yInd = 0;
>               if (++xInd == data.size())
>                   result = 0;
>           }
>       }
>   ...
>

Isn't <something>.size() a method or function call? We'd also want to
eliminate that needless activity from the loop by defining "zMax =
data[xInd][yInd].size()", and etc., before the loop.

Just because C++ gifts you with 'high-level' abstractions, that
doesn't confer an automatic excuse to create inefficient,
unmaintainable code.
From: Keith Thompson on
Nathan <nathancbaker(a)gmail.com> writes:
[...]
> ,---
> result = value
> xInd = 0
> yInd = 0
> zInd = 0
> while ( data[xInd][yInd][zInd] != value && result != 0)
> {
> ++zInd;
> if (( zInd < data[xInd][yInd].size() ) != true ) { zInd = 0; +
> +yInd};
> if (( yInd < data[xInd].size() ) != true ) { yInd = 0; ++xInd};
> if (( xInd < data.size() ) != true ) { result = 0 };
> }
> return result
> `---
[...]

A style point: comparisons to true and false are almost always
superfluous. Rather than
if (( xInd < data.size() ) != true )
just write
if ( xInd <= data.size() )

As for the overall structure of your proposed replacement, you've
replaced three nested loops with one loop and three if statements.
Furthermore, the original version only tests zInd on most iterations;
your version tests zInd, yInd, and xInd on every iteration.

The original problem is to traverse a 3-dimensional array. A triple
nested loop is the most obvious way to do that. There might be
some advantages in converting it to a single loop, but clarity
isn't one of them, at least in this case.

--
Keith Thompson (The_Other_Keith) kst-u(a)mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"