Subject: Re: [boost] Interest in StaticVector - fixed capacity vector
From: Andrew Hundt (athundt_at_[hidden])
Date: 2011-10-14 19:24:11
>>> Is throwing an exception going to turn an incorrect program into a
>>> correct one?
>> If you catch that exception and do something reasonable, would it not?
> No. "Reasonable" doesn't mean you fulfill your original
> intention/specification. You don't normally write specifications that
> say, "...unless the code is wrong, in which case I'll do something
I'm fairly certain that writing specifications this way is quite
common. For instance, consider a program that catches exceptions and
crashes, then generates and sends a bug report to the creators. Does
that application not catch when the code is wrong, then do something
reasonable? Of course this is not correct behavior with respect to the
original goal, but I would argue that is is correct behavior with
respect to a secondary goal of finding incorrect behavior that
prevents reaching the original goal.
Furthermore, I don't believe I am being very original with this idea.
Java has the ArrayOutOfBounds exception. Please, I beg you not to take
this as the belief that Java is correct. I am simply unconvinced by
your argument and I am playing devil's advocate by pointing out an
example counter to the point you are making.
> nor do you code to perform an operation in two different
> ways in case one of them turns out to have coding errors, do you?
I believe this is typically done by the competition. :-)
>> Perhaps this only makes the argument of making it "less wrong".
> Is that like "less pregnant?"
Yep. That is exactly what I was trying to say. :-)
> More precisely, it avoids some undefined behaviors, which has some
> security benefits. That's why I proposed the SEMISECURE mode.
Why should the mode be SEMISECURE by default, and not a
RELAXED_SECURITY mode for when you absolutely need the highest
also, what is the disadvantage of providing, push_back(),
checked_push_back(), and unchecked_push_back(), where a policy or
struct tag allows the checkedness (pardon my word frankenstein) to be
decided at either the instantiation or the call site, respectively?
To draw an analogy, designing code to use RAII can sometimes incur a
performance penalty with the benefit of preventing a failure to
release a resource. Of course you can always "just free" that resource
by hand, but changes in one portion of an application can have
unforeseen consequences in another to those who are dealing with a
small portion of a very large or complex system. Therefore it has
become commonplace to pay a small penalty for the benefit of
preventing problems. In this case, that problem is undefined behavior,
and the penalty is the checks. Perhaps an out of bounds error does not
meet the complexity level required for such a cost to be worthwhile,
but if I am not mistaken myself, it is one of the most common mistakes
made by anyone. However, this does not prevent one from making the
other choice, and calling the unchecked version when they absolutely
need the performance.
The core of what I am saying is that checks + exceptions make it
easier to find, prevent, and/or report problems.
There are a some items I would like to verify so I can clarify my
understanding of your argument.
First, I believe that you are saying that code is already incorrect
when it goes out of bounds, so you might as well just let it keep
running with undefined behavior unless a special SEMISECURE flag is
set. Furthermore, by the time you reach the point where I am proposing
that an exception be thrown, the code is already incorrect, therefore
the exception will never prevent an error, and thus the exception
should not exist. Is this correct?
What are the metrics by which you define an exception as both
incorrect and/or worse? What is lost by using an exception? Does it
break a convention, reduce performance, break purity, or upend general
>>>>> How could it ever be a "drop-in replacement for vector" when it comes to
>>>>> exceeding a reasonably low length bound? A vector is probably going to
>>>>> succeed to push_back past that bound, while this class definitely won't.
>>>>> Unless you plan to intentionally leverage this exception (in which case
>>>>> vector wasn't serving your needs, so your code needs more than a
>>>>> "drop-in-replacement" anyway), then it's *going* to change the behavior
>>>>> of your program if and when you cause it to be thrown.
>>>>> Maybe I'm missing something.
>>>> - Perhaps one uses vector while prototyping on their nice quad core 64
>>>> bit machine, then they need to cut things down and set strict limits
>>>> once the prototype works to get it on their cell phone, game console,
>>>> or even smaller device like a router or radio chip.
>>> Yeah... in that case they almost certainly don't want to pay for the
>>> check. But if they do want a check, how is an exception going to help
>> Black box:
>> If you have to use an existing algorithm or function that you cannot
>> change or do not know exactly how the internals work, you can catch
>> the exception and handle it in a reasonable way.
> Too much hand-waving. What possible "reasonable way?" Are you going to
> try to achieve the same semantics in a different way?
I would expect to most frequently use it to report the problem.
> [And why "how the internals work" matters is beyond me].
>> Alternately, if you are creating the black box, you could do the same
>> for the data they give you.
>> I find exceptions helpful when they immediately kill my program when I
>> do something wrong at the prototyping stage, as compared to random
>> stack jumps into other places when I'm just allowed to try and access
>> that memory. Much easier to find and fix quickly :-)
> Thus a recommendation for a SEMISECURE mode where you can tune the
> response. The builtin assert() facility almost always kills your
> program at /least/ as usefully and quickly as an exception.
Ah, this is at least a partial answer to my questions above. Is it
also straightforward possible to handle an assert and report it if the
programmer is not present to witness it?
>>>> - On the completely opposite end of the spectrum, processing an extremely large
>>>> dataset that has fixed size datums. One could again prototype with vectors,
>>>> but now they need something a bit more constrained to optimize
>>>> performance for their datacenter.
>>> Again, how does the exception help? How do you use that?
>> The execution of what?
> Did I write "execution?"
my ability to read failed me :-). Here I was advocating how drop-in
replacement of std::vector with StaticVector would be useful.
Exceptions would help StaticVector achieve this because std::vector
throws one when there is no more space.
I'm sure there is a gaping whole in my argument somewhere, so please
poke away :-)