is delete[] necessary?

B

Bo Persson

John said:
"Gerhard Fiedler" wrote >
I think in the example above, not using break would be obfuscation
and unnecessary complication, similar to some C code that would be
perfectly structured and readable with a few judiciously placed
gotos and gets convoluted and complicated just because the author
thought that "gotos are (always and in all ways) bad".
Gerhard

Thanks for that, Gerhard. I needed to 'hear' it.
"Always and in all ways" no GOTOs should maybe a guideline be (that
I grasp and may agree with), but Red Flags go up in me in almost
any subject where I run into one of those absolutes like "never" or
"there are no exceptions."

(Pardon: I've seen one objection to this thread I started, so I
guess I'm in some violation or other, and will take any non-"is
delete[] necessary"-thread questions to a new thread.
Thanks lastly and to all for the help!)

Some are more "never" that others.

With goto the case is that some of us have done this professionally
for 20 or 30 years, and have never ever found a good use for a goto.
Isn't it strange that you found one almost immediately? :)


There are places where a break out of a loop might be useful, but not
that many. Very often, the scare of having to evaluate a condition
more than once, can be solved by a loop that looks like this

while (!Done)
{
// some processing
}

Whenever you realize that the processing is done, set Done to true.
Then you know.


Bo Persson
 
K

kwikius

J

John Brawley

Bo Persson said:
Some are more "never" that others.

With goto the case is that some of us have done this professionally
for 20 or 30 years, and have never ever found a good use for a goto.
Isn't it strange that you found one almost immediately? :)

Perhaps I had a uniquely unusual problem to solve....?
(I take the gentle rebuke kindly...)
There are places where a break out of a loop might be useful, but not
that many. Very often, the scare of having to evaluate a condition
more than once, can be solved by a loop that looks like this

while (!Done)
{
// some processing
}

Whenever you realize that the processing is done, set Done to true.
Then you know.

Indeed. But in a case like mine, where where the processing is never 'done'
and where its state must be judged by the user 'live,' one needs an external
(user-caused) way to stop the process. I think that in my case exit from
the loop _must_ be done from outside the program (which is pretty much
itself, the loop). A keypress detected inside the loop and linked to a GOTO
end: does the trick without fuss.

I can see why many GOTOs used to jump around from place to place inside a
program would be unwanted and bad practice. Using one once, like a nuclear
bomb and only in the "downward" direction, cleanly gets the job (mine,
anyway) done.

(Thanks for the additional words, Gerhard.)
 
J

John Brawley

"kwikius" wrote
>
John Brawley" said:
delete[] label; // is this _necessary_ in this case?
Yes.
What is not neccessary are questions like that and threads
of non-discussion they generate.
Hi again John.
<snip reply>
Fora hint as to what's going on here, look up "Troll":
http://en.wikipedia.org/wiki/Internet_troll
Best thing to do is simply to do absolutly nothing.
regards
Andy Little

Ah. URL unnecessary.
(Old, known word, from long ago (BBSs).
I ran one.)
Wrong.
Original question was dead serious, its intent to get an answer:
Subsequent interaction added also-needed info.
No trolling (no need: I have hours-a-day of email-based interests; I don't
need UseNet but rarely), but extending thread _has_ awakened a few
Netiquette Police who make assumptions with hubris, without cause.
Strictures.
You're right, but deprive me of pertinent C++ info?
OK.
End of subthread.
'Bye.
 
J

James Kanze

Is this your (plus a few other's) personal opinion, or is
there some evidence that this is more than opinion?

What sort of evidence? I've worked on all sorts of code, and
it's systematic---anytime there's a break from a loop, the code
has been pretty much unreadable and needing rework. It's pretty
much an established engineering principle, for those who care to
study software engineering.
For example something like this:
apiType result;
for(;;)
{
callSomeApi( result );
if( someCondition( result ) )
break;
callSomeOtherApi( result );
}

That's pretty vague. It doesn't mean anything as written.
Start by giving it more meaningful names, corresponding to
something real, and you'll probably end up with something
similar, and probably without the break.

(Actually, of course, there are a lot worse things you can do.
I wouldn't object too much to the break if it's the only way you
exit the loop. The important thing is that you do only exit
from a single point.)
AIUI, this can be transformed into a "non-break" solution in
various ways, but they either duplicate code (for example a
pre-loop call to the setup function) or introduce an
additional boolean -- with the only purpose to get rid of the
break, without increasing clarity or improving anything at
all.

I *think* what you're talking about is the so-called loop and a
half. Which also corresponds to your example. In actual
practice, I've found that the duplicated code or extra
conditions only become a problem if the loop itself is too big.
Once you break it down into reasonably sized functions, you
generally end up with a more classical loop as well.
I think in the example above, not using break would be
obfuscation and unnecessary complication, similar to some C
code that would be perfectly structured and readable with a
few judiciously placed gotos and gets convoluted and
complicated just because the author thought that "gotos are
(always and in all ways) bad".

Actually, every time I've seen goto's in C, C++ or Pascal, it's
been because the author has written functions which were too big
and convoluted. Correct fonctional break down results in
cleaner code, without the goto's.
 
J

James Kanze

"James Kanze" wrote

[...]
-- There are some things that really can't be verified simply
by testing. The most obvious is the readability and
maintainability of the code---important issues in most
cases. But there are also a lot of threading issues which
don't lend themselves to testing, and some floating point
issues as well.
Please, you bring up a worry: you say some floating point
issues don't lend themselves well to testing. I use double
precision floating point almost everywhere, and the program
when running is in a constant state of doing repeated
Pythagorean 3D distance calcs and such.
What tests would have issues with floating piont, if your
answer would be a) of interest to you or others or b) not
wildly offtopic?

Floating point is very, very tricky, because it's not linear.
Which means that at least in principle, and algorithm might work
for two values very, very near one another, and fail for a value
in between them. (And of course, the number of possible
floating point values generally precludes exhaustive testing.)
The result is that you do very, very careful numerical anaysis
to prove that your algorith will behave linearly over a given
range, despite the descrete nature of machine floating point,
then test the ends of the range exhaustively, and add a few
random tests elsewhere. In some cases, in fact, you'll find
that you'll have to use two different algorithms, depending on
the input, since no one algorithm will be linear over the entire
range---in such cases, of course, you'll test very insensively
around the switch-over point.
(My "tests" so far have consisted of simple right-answer
checks and of sending the .exe I write with Windows 98 to
friends with different operating systems --albeit all
Micro$soft'$-- and seeing if it chokes and dies or not. (So
far, not.))

Right-answer checks for what input? The problem is that an
algorithm which gives a correct answer for some input might give
a wrong answer for other input. (Although I've never actually
seen the case, I've heard stories---and it sounds plausible---of
functions that returned the correct answer for all but two or
three values in the entire floating point range. In one case,
at least, there were just a couple of values where the function
failed to converge, due to imprecisions in the floating point
arithmetic, and the program went into an endless loop.)
-- Knowing how to write effective tests is a software
engineering issue in itself, and is in some ways more
difficult that writing C++ or even good design (although
good design generally should lead to effective tests---in
both cases, you need to think about the corner cases, and be
sure they're handled correctly).
std::vector, I don't think that the first is really much of an
issue, but given what John has said of his background, the
second very well could be.
Thank you. I'm unsure if it would be. The program is so
simple in concept (if difficult --for me-- to implement), that
it's unlikely extensive tests of its functioning would tell me
much more than I already know, but it's critical that it run
without problems on other people's machines.

If you're using floating point, be very cautious about numeric
stability. Machine floating point are NOT real numbers, and
many of the rules of real number arithmetic don't always hold:
e.g. (a + b) + c != a + (b + c) in many cases.
 
J

James Kanze

"kwikius" wrote
"John Brawley" wrote:
>
John Brawley" said:
delete[] label; // is this _necessary_ in this case?
Yes.
What is not neccessary are questions like that and threads
of non-discussion they generate.
Hi again John.
<snip reply>
Fora hint as to what's going on here, look up "Troll":
http://en.wikipedia.org/wiki/Internet_troll
Best thing to do is simply to do absolutly nothing.
regards
Ah. URL unnecessary.
(Old, known word, from long ago (BBSs).
I ran one.)
Wrong.
Original question was dead serious, its intent to get an answer:
Subsequent interaction added also-needed info.
No trolling (no need: I have hours-a-day of email-based interests; I don't
need UseNet but rarely), but extending thread _has_ awakened a few
Netiquette Police who make assumptions with hubris, without cause.
Strictures.
You're right, but deprive me of pertinent C++ info?
OK.
End of subthread.

I don't think anyone was accusing you of trolling. It seemed
obvious to me that you really were looking for information. On
the other hand, the comment "What is not necessary are questions
like that [...]" could very definitly be taken as a troll.
 
R

red floyd

John said:
"kwikius" wrote
John Brawley" said:
>
John Brawley" said:
delete[] label; // is this _necessary_ in this case?
Yes.
What is not neccessary are questions like that and threads
of non-discussion they generate.
Hi again John.
<snip reply>
Fora hint as to what's going on here, look up "Troll":
http://en.wikipedia.org/wiki/Internet_troll
Best thing to do is simply to do absolutly nothing.
regards
Andy Little

Ah. URL unnecessary.
(Old, known word, from long ago (BBSs).
I ran one.)
Wrong.
Original question was dead serious, its intent to get an answer:
Subsequent interaction added also-needed info.
No trolling (no need: I have hours-a-day of email-based interests; I don't
need UseNet but rarely), but extending thread _has_ awakened a few
Netiquette Police who make assumptions with hubris, without cause.
Strictures.
You're right, but deprive me of pertinent C++ info?


John, James mentioned this, and I tend to agree: The troll was Krice and
his crud about "what is not necessary are questions like that". Your
question is legit, whether we personally agree with your implementation
or not.

Please continue to hang out here, I know it's helped me become a better
C++ programmer, and I know it's helped others as well.
 
G

Gerhard Fiedler

That's pretty vague. It doesn't mean anything as written.

Maybe not, but the idea is quite simple (and probably not foreign to an
experienced programmer): there is something that needs to be done to set
something up or attempt to acquire some data or resources (may be a 3rd
party API that can't be changed), a condition checked that determines the
loop end, and if no loop end, something needs to be done. This is a pretty
common scenario.
Start by giving it more meaningful names, corresponding to something
real, and you'll probably end up with something similar, and probably
without the break.

No. It's just like this. I could change the names, but that wouldn't change
the structure.
(Actually, of course, there are a lot worse things you can do. I wouldn't
object too much to the break if it's the only way you exit the loop.
The important thing is that you do only exit from a single point.)

Bingo... and here we go. The break is not the bad guy anymore, it's the
(possible) bad use of the break. This is exactly what I meant.

I *think* what you're talking about is the so-called loop and a half.
Which also corresponds to your example. In actual practice, I've found
that the duplicated code or extra conditions only become a problem if
the loop itself is too big.

The duplicated code is not a problem -- but the question is why duplicate
it in the first place? What do I gain? Just avoiding the break is not a
gain in itself. The code is readable, it should be immediately clear to
anybody who understands a minimum of programming structures -- so where's
the problem that I would solve by using a non-break loop solution and
duplicate code?

FWIW, I thought that not using duplicate code is also a principle of good
program structure... :)

Also FWIW, these guys (the first Google hit on "loop and a half" :) seem to
agree with me
Once you break it down into reasonably sized functions, you generally end
up with a more classical loop as well.

This loop above looks pretty classical to me.
Actually, every time I've seen goto's in C, C++ or Pascal, it's been
because the author has written functions which were too big and
convoluted. Correct fonctional break down results in cleaner code,
without the goto's.

There's all kind of software, with all kinds of trade-offs... Maybe you
don't program a lot on 8-bit systems these days (not in C++, but in C or
Pascal) with severely restricted resources and other constraints where
breaks and gotos do make sense occasionally -- IMO, of course, and used
with care.


In general, I agree with you -- but "in general" doesn't mean "always".
"Always" and "never" are really strong terms, and I tend to think there's
no such thing in the real world as rules that are always valid. At least,
they are quite difficult to positively prove... "It hasn't occurred to me"
is definitely something else.

Gerhard
 
J

Jerry Coffin

[ ... ]
Is this your (plus a few other's) personal opinion, or is there some
evidence that this is more than opinion?

Anything to do with what's right (at least in programming) is ultimately
a matter of opinion. In the '70s (or so) people studying structured
programming came up with a few specific structures with which all
possible programming can be done. Some postulated that it was better if
only those structures were used. A break is clearly a goto in (thin)
disguise, and clearly is NOT one of those structures (though its use in
a switch statement is necessary to produce the selection structure).

The battle over strict adherence to structured programming raged for
years, and clearly isn't entirely over yet. Many people (myself
included) allow that there may be exceptions -- but most of them (again,
including me) have a hard time remembering making such an exception.
For example something like this:

apiType result;
for(;;)
{
callSomeApi( result );
if( someCondition( result ) )
break;
callSomeOtherApi( result );
}

AIUI, this can be transformed into a "non-break" solution in various ways,
but they either duplicate code (for example a pre-loop call to the setup
function) or introduce an additional boolean -- with the only purpose to
get rid of the break, without increasing clarity or improving anything at
all.

Not so. This can be written with no break, no code duplication, and no
extra boolean. In fact, the appearance of a problem only arises because
callSomeApi has been designed to return a result, but not by actually
_return_ing the result it produces. With that fixed, the code becomes
obvious

apiType result;
while (!someCondition(result=callSomeApi()))
callSomeOtherApi(result);

Even without fixing that, however, a clear solution is fairly
straightforward:

apiType result;
while (callSomeApi(result), !someCondition(result))
callSomeOtherApi(result);
I think in the example above, not using break would be obfuscation and
unnecessary complication, similar to some C code that would be perfectly
structured and readable with a few judiciously placed gotos and gets
convoluted and complicated just because the author thought that "gotos are
(always and in all ways) bad".

I have to disagree. I think either solution above is superior to using
break. The first is clearly preferable, but the second is acceptable as
well. I see no good reason for using break in this situation.
 
A

Alf P. Steinbach

* Jerry Coffin:
This can be written with no break, no code duplication, and no
extra boolean. In fact, the appearance of a problem only arises because
callSomeApi has been designed to return a result, but not by actually
_return_ing the result it produces. With that fixed, the code becomes
obvious

apiType result;
while (!someCondition(result=callSomeApi()))
callSomeOtherApi(result);

Even without fixing that, however, a clear solution is fairly
straightforward:

apiType result;
while (callSomeApi(result), !someCondition(result))
callSomeOtherApi(result);


I have to disagree. I think either solution above is superior to using
break. The first is clearly preferable, but the second is acceptable as
well.

Nah.

It's conventional, but the convention is really the old C one of using
maximum side-effects in expressions, obfuscation-style terse code.

Trading a clear 'break' for an unclear side-effect and terse code is
absolutely not an improvement, or even acceptable, and it doesn't make
sense in any way except the urge to conform to a silly convention used
by others of one's peers, i.e., social pressure and social adaption.


I see no good reason for using break in this situation.

It's simplest and most clear, best supports mainainance.

That's good.


Cheers,

- Alf
 
K

kwikius

"kwikius"  wrote
 "John Brawley"  wrote:
>
John Brawley" said:
delete[] label; // is this _necessary_ in this case?
Yes.
What is not neccessary are questions like that and threads
of non-discussion they generate.
Hi again John.
<snip reply>
Fora hint as to what's going on here, look up "Troll":
http://en.wikipedia.org/wiki/Internet_troll
Best thing to do is simply to do absolutly nothing.
regards
Andy Little

Ah.  URL unnecessary.
(Old, known word, from long ago (BBSs).
I ran one.)
Wrong.
Original question was dead serious, its intent to get an answer:
Subsequent interaction added also-needed info.
No trolling (no need: I have hours-a-day of email-based interests; I don't
need UseNet but rarely), but extending thread _has_ awakened a few
Netiquette Police who make assumptions with hubris, without cause.
Strictures.
You're right, but deprive me of pertinent C++ info?
OK.
End of subthread.
'Bye.

Sorry John. I should have been clearer. I was referring to Krice.

regards
Andy Little
 
J

James Kanze

On 2008-01-28 20:55:21, James Kanze wrote:
Maybe not, but the idea is quite simple (and probably not
foreign to an experienced programmer): there is something that
needs to be done to set something up or attempt to acquire
some data or resources (may be a 3rd party API that can't be
changed), a condition checked that determines the loop end,
and if no loop end, something needs to be done. This is a
pretty common scenario.

It's the loop and a half idiom. I know. My point is that
whenever one starts considering concrete examples, it turns out
the the best solution involves putting the different parts in
separate, named functions, which reduces it to a simple loop.

There are probably exceptions, but they're rare enough that I've
not encountered them in the last thirty years.
No. It's just like this. I could change the names, but that
wouldn't change the structure.

No, but given a concrete instance, a different structure might
suggest itself as being even more appropriate. That's been my
experience, anyway.
Bingo... and here we go. The break is not the bad guy anymore,
it's the (possible) bad use of the break. This is exactly what
I meant.

Well, it's obvious that some use are worse than others. The
case of the loop and a half is probably the least bad, because
the loop still does have a single exit, and the reader, seeing
the 'for (;;)' (or a 'while (true)', or whatever) knows that he
has to look for the exit elsewhere. It's still not as good as
having the exit condition displayed prominently at the top, and
having the preconditions defined by the exit condition hold
through the entire loop. (In your example, for example, "!
someCondition( result )" is an invariant for the second half of
the loop, and for all but the first execution of the first half.
Try reasoning about that.)
The duplicated code is not a problem -- but the question is
why duplicate it in the first place? What do I gain? Just
avoiding the break is not a gain in itself. The code is
readable, it should be immediately clear to anybody who
understands a minimum of programming structures -- so where's
the problem that I would solve by using a non-break loop
solution and duplicate code?
FWIW, I thought that not using duplicate code is also a
principle of good program structure... :)

The point is that it isn't really duplicate, regardless of
appearances, since the pre-conditions and the invariants are
different. The duplication is in fact only superficial.
Also FWIW, these guys (the first Google hit on "loop and a half" :) seem to
agree with me
<http://www.cs.duke.edu/~ola/patterns/plopd/loops.html#loop-and-a-half>.
Looks to me as if it weren't that clear of a consensus that break is bad.

Looks to me as if hackers are everywhere:).

Seriously, I do wonder about the competence of someone who can
present linear search without mentionning the loop invariants or
the proof of progress. I wouldn't give much for the reliability
or the correctness of the code they write.
This loop above looks pretty classical to me.

The problem is that you don't establish the loop invariant until
the middle of the loop, which means that it will not hold for
part of the loop the first time through.
There's all kind of software, with all kinds of trade-offs...
Maybe you don't program a lot on 8-bit systems these days (not
in C++, but in C or Pascal) with severely restricted resources
and other constraints where breaks and gotos do make sense
occasionally -- IMO, of course, and used with care.

If you're talking about rewriting working code to make it fit
some very stringent external constraints, that's a different
matter. When the profiler says you must, you must. But that
doesn't make the results any cleaner.
 
J

James Kanze

[ ... ]
Is this your (plus a few other's) personal opinion, or is
there some evidence that this is more than opinion?
Anything to do with what's right (at least in programming) is
ultimately a matter of opinion.

I'm not sure that that's totally true. There have been some
actual experiments with some minor details---I seem to recall
reading about one showing that new programmers learned a
language faster and made less errors when statements were
terminated (as in C/C++) rather than separated (as in Pascal).
But I don't think that there have been such studies for larger
scale issues, such as this. Except indirectly, perhaps: the
percentage of companies forbidding such use rises with the SEI
maturity level, for example. But that doesn't say much about
cause and effect. And I'm not sure that such information is
actually available, either. All I can say is that in the
companies I've been in, a rise in the SEI maturity level has
been accompanied with stricter coding guidelines, and that
forbidding break except in a switch has been part of the
strictest guidelines.
In the '70s (or so) people studying structured programming
came up with a few specific structures with which all possible
programming can be done. Some postulated that it was better
if only those structures were used. A break is clearly a goto
in (thin) disguise, and clearly is NOT one of those structures
(though its use in a switch statement is necessary to produce
the selection structure).
The battle over strict adherence to structured programming
raged for years, and clearly isn't entirely over yet. Many
people (myself included) allow that there may be exceptions --
but most of them (again, including me) have a hard time
remembering making such an exception.

On the other hand, a lot of us have had to maintain code which
didn't respect them, and that's left a very bad taste in our
mouths.
Not so. This can be written with no break, no code
duplication, and no extra boolean. In fact, the appearance of
a problem only arises because callSomeApi has been designed to
return a result, but not by actually _return_ing the result it
produces. With that fixed, the code becomes obvious
apiType result;
while (!someCondition(result=callSomeApi()))
callSomeOtherApi(result);

I'm not sure that I like the embedded assignment, at all.

I think the real problem is that the break-up into different
functions is wrong. But without any concrete semantics, how can
you say. I would guess, however, that in most cases, something
like the standard istream idiom would be more appropriate:

while ( callSomeApi( result ) ) {
doSomethingWith( result ) ;
}

It's very much standard practice to have a function with side
effects return a success/failure indication, which can be used
as a condition in a loop or if. I'm not overly thrilled by
anything in the condition having side effects, but in this case,
it's so ubiquious, I think I'll have to live with it. Even
cleaner would be:

initialize() ;
while ( condition ) {
doSomething() ;
update() ;
}

This is the best solution *even* when "initialize()" and
"update()" are apparently the same (i.e. consist in exactly the
same sequence of tokens). Because despite appearences,
initialization is not update---in particular, update supposes
that the loop invariants have already been established.

To rewrite this using the original names, you'd get:

apiType result = callSomeApi() ;
while ( someCondition( result ) ) {
callSomeOtherApi( result ) ;
result = callSomeApi() ;
}

Notice that despite the superficial similarity in the
initializataion and the update, in C++, they are two very
different operations: initialization and assignment. C++ (more
than many languages) actually recognizes this difference:
initialization (constuctor) establishes object invariants
(supposing nothing previously), assignment supposes that the
invariants hold.
Even without fixing that, however, a clear solution is fairly
straightforward:
apiType result;
while (callSomeApi(result), !someCondition(result))
callSomeOtherApi(result);

Never. In this case, the cure is worse than the disease. If
you need the comma operator, beware.

The clear solution is for callSomeApi to return apiType---or to
wrap it in a function which does. And not have an uninitialized
variable floating around.
 
A

Alf P. Steinbach

* James Kanze, about "loop-and-a-half":
The problem is that you don't establish the loop invariant until
the middle of the loop, which means that it will not hold for
part of the loop the first time through.

That is a specious argument. When the top half of the loop code is
moved into the continuation condition checking, the complexity isn't
reduced: it's increased. You now need to consider loop invariants not
only for the syntactical loop body but also for the condition checking,
and the problem of first-time execution (if it is) exists also there.

This in addition to more unreadable code and artificial structure.


Cheers, & hth.,

- Alf
 
G

Gerhard Fiedler

It's the loop and a half idiom. I know. My point is that
whenever one starts considering concrete examples, it turns out
the the best solution involves putting the different parts in
separate, named functions, which reduces it to a simple loop.

By "best" you mean with the least amount (that is, no) break. But that is
circular reasoning... this type of loop in this form is clear, easily
understandable and maintainable and wouldn't gain anything by combining
parts of it into a separate function just to get rid of the break (and even
less by using C-style obfuscation techniques; joining several statements
into a single expression :)

So this is the best solution -- for some values of "best" :)

Your point was that besides personal style, not using break is a generally
recognized principle of software engineering. A search through available
literature doesn't seem to confirm this. It may not be your preference, and
when programming for you I certainly could and would adhere to your
preference, but otherwise there seem to be enough people in software
engineering that don't have any issue with the sort of clarity and
simpleness that this structure conveys.

I never wanted to say that using break is necessary. But it may be
adequate.
Well, it's obvious that some use are worse than others. The case of the
loop and a half is probably the least bad, because the loop still does
have a single exit, and the reader, seeing the 'for (;;)' (or a 'while
(true)', or whatever) knows that he has to look for the exit elsewhere.
It's still not as good as having the exit condition displayed
prominently at the top, and having the preconditions defined by the exit
condition hold through the entire loop.

You seem to say here that the only loop you find "good" is the while loop
(with the condition at the top). So no condition in the middle, and also
not at the end?
(In your example, for example, "! someCondition( result )" is an
invariant for the second half of the loop, and for all but the first
execution of the first half. Try reasoning about that.)

The example was probably a bit too simplified.

uint8_t *buf;
uint32_t size;
for(;;)
{
size = getBuffer( buf );
if( size >= whatWeNeed )
break;
increaseBuffer();
}
// work on buf

I know that this can be "simplified" in some obfuscated early C style
manner. I agree with Alf and don't really find that clearer. It also can be
rewritten by duplicating any part of it. Again, it is a question of
personal style and not generally accepted practice to do it one way or the
other (which is my point).

Looks to me as if hackers are everywhere:).

Seriously, I do wonder about the competence of someone who can present
linear search without mentionning the loop invariants or the proof of
progress. I wouldn't give much for the reliability or the correctness
of the code they write.

They are not the only ones (maybe do the search... there are a few relevant
results with relevant examples). Point is it doesn't seem unanimous that
"break is bad". And other than "it is generally considered as bad" (which
is wrong, as we've seen) there hasn't been any real argument presented
about /why/ it is supposed to be bad. All the arguments were about that
there are other alternatives -- which is true. But what's in those
alternatives that makes them better?

The problem is that you don't establish the loop invariant until
the middle of the loop, which means that it will not hold for
part of the loop the first time through.

The thing with the break in the middle is that there is generally no loop
invariant, if I understand you correctly here.

If you're talking about rewriting working code to make it fit some very
stringent external constraints, that's a different matter. When the
profiler says you must, you must. But that doesn't make the results any
cleaner.

But better -- in the sense of "fits the requirements". If a break or a goto
helps to do that, then it is "good programming" in my book. Which was
simply to counter the "never" part of the argument (as in "never say never"
:)

Gerhard
 
G

Gerhard Fiedler

If you're using floating point, be very cautious about numeric
stability. Machine floating point are NOT real numbers, and
many of the rules of real number arithmetic don't always hold:
e.g. (a + b) + c != a + (b + c) in many cases.

Which boils down to "never use (in)equality comparison with floating point
numbers".

OTOH, abs(((a + b) + c) - (a + (b + c))) < epsilon can be safe, with
appropriate choice of epsilon.

Gerhard
 
J

John Brawley

"red floyd">
John said:
"kwikius" wrote
John Brawley" said:
>
"John Brawley" > wrote:
delete[] label; // is this _necessary_ in this case?
Yes.
What is not neccessary are questions like that and threads
of non-discussion they generate.
Hi again John.
<snip reply>
Fora hint as to what's going on here, look up "Troll":
Original question was dead serious, its intent to get an answer:
Subsequent interaction added also-needed info.
John, James mentioned this, and I tend to agree: The troll was Krice and
his crud about "what is not necessary are questions like that". Your
question is legit, whether we personally agree with your implementation
or not.

Please continue to hang out here, I know it's helped me become a better
C++ programmer, and I know it's helped others as well.

Thank you very much indeed.
I thought I was being dumped on; now see that wasn't it.
I'll hang out, (and continue following this thread of interest), but my
questions have been addressed and if I need another one (I have another one)
treated I'll open a new thread for it.

Thanks again.
I am getting better at it myself, even if I only have one program to work on
and improve.
(Hard stuff comin': I gotta do some OpenGL stuff so's I can again _see_
what's going on inside the program.)

People like you make UseNet worth visiting again.
 
J

John Brawley

John Brawley said:
>
John Brawley" said:
delete[] label; // is this _necessary_ in this case?
Yes.
What is not neccessary are questions like that and threads
of non-discussion they generate.
Hi again John.
<snip reply>
Fora hint as to what's going on here, look up "Troll":
http://en.wikipedia.org/wiki/Internet_troll
Best thing to do is simply to do absolutly nothing.
regards
Andy Little

Ah. URL unnecessary.
(Old, known word, from long ago (BBSs).
I ran one.)
Wrong.
Original question was dead serious, its intent to get an answer:
Subsequent interaction added also-needed info.
No trolling (no need: I have hours-a-day of email-based interests; I don't
need UseNet but rarely), but extending thread _has_ awakened a few
Netiquette Police who make assumptions with hubris, without cause.
Strictures.
You're right, but deprive me of pertinent C++ info?
OK.
End of subthread.
'Bye.
Sorry John. I should have been clearer. I was referring to Krice.
regards
Andy Little

_I_ am sorry also, Andy. I realized that was the case after I'd written the
post.
(It's been a long, long time since I used to run into UseNet's
peculiarities...)

You have been helpful and kind; I owe you an apology as well.
(And, I think this subthread has exhausted itself... eh?)
(*grin*)

Have a nice day and thank you very much.
 
J

John Brawley

"James Kanze"
"James Kanze" wrote

[...]
cases. But there are also a lot of threading issues which
don't lend themselves to testing, and some floating point
issues as well.
Please, you bring up a worry: you say some floating point
issues don't lend themselves well to testing. I use double
What tests would have issues with floating piont, if your
answer would be a) of interest to you or others or b) not
wildly offtopic?
Floating point is very, very tricky, because it's not linear.
Which means that at least in principle, and algorithm might work
for two values very, very near one another, and fail for a value
in between them. (And of course, the number of possible
floating point values generally precludes exhaustive testing.)
The result is that you do very, very careful numerical anaysis
to prove that your algorith will behave linearly over a given
range, despite the descrete nature of machine floating point,
then test the ends of the range exhaustively, and add a few
random tests elsewhere. In some cases, in fact, you'll find
that you'll have to use two different algorithms, depending on
the input, since no one algorithm will be linear over the entire
range---in such cases, of course, you'll test very insensively
around the switch-over point.

Thank you very much.
I'm aware the machine itself can (and does) generate "rounding errors" that
vary, much as you describe (close-to-same floats, perhaps error beyond the
fifteenth(?) decimal place).

My implementation is likely not suffering: I haven't seen a single exception
thrown by the operating system even in literally days of continuous running
flat-out.

I also have a suspicion that the error(s) may _help_ me: the program deals
with points tight against one another (this is oddball geometry) in a 3D
space. Without details, it's possible for two to get 'stuck' inside a
'cage' of twelve, hence be right on top of each other, to extreme precision
beyond the double's . I suspect that the seemingly random machine
rounding error can cause them to be _not_ right on top of each other, enough
to un-stick them.
(Pardon wordiness; I know the purpose of the program isn't of interest, only
its coding is (maybe).)
(My "tests" so far have consisted of simple right-answer
checks and of sending the .exe I write with Windows 98 to
friends with different operating systems --albeit all
Micro$soft'$-- and seeing if it chokes and dies or not. (So
far, not.))
(block quote)
Right-answer checks for what input? The problem is that an
algorithm which gives a correct answer for some input might give
a wrong answer for other input. (Although I've never actually
seen the case, I've heard stories---and it sounds plausible---of
functions that returned the correct answer for all but two or
three values in the entire floating point range. In one case,
at least, there were just a couple of values where the function
failed to converge, due to imprecisions in the floating point
arithmetic, and the program went into an endless loop.)

Right answer checks to see if I'm doing something stupid.
(*g*) Inputs to my specialized calculation functions are things I can't
directly check very easily, and what the program does makes it essentially
irrelevant even if there were a (tiny? not large?) floating point error
(except for the helper error maybe, abovementioned): numbers exist for so
fleeting a time before being changed (xyz coords, mostly), that any error
can't propagate or concatenate. It gets swamped, fuzzed out.
If the graphical output (I use an accessory program to see) is what it's
supposed to be --and it always is-- then the errors if they exist for micro-
or nano-seconds, are not a problem for me.

I was worried when you said that about floating point issues, that you knew
something C++-specific that might have amplified these errors, but I see
that's probably not the case.
Inputs

<...>

If you're using floating point, be very cautious about numeric
stability. Machine floating point are NOT real numbers, and
many of the rules of real number arithmetic don't always hold:
e.g. (a + b) + c != a + (b + c) in many cases.

I was more or less aware, but needed to know what you meant.
I thank you _very_ much.
 

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

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,135
Latest member
VeronaShap
Top