Topic: Standard library exception specifications might be lacking


Author: dave@boost-consulting.com (David Abrahams)
Date: Mon, 15 Oct 2007 18:15:15 GMT
Raw View
on Sat Sep 22 2007, rani_sharoni-AT-hotmail.com wrote:

> On Sep 21, 11:10 pm, gre...@pacbell.net (Greg Herlihy) wrote:
>> So a C++ programmer does not have to
>> wonder whether a particular Standard Library routine throws exceptions or
>> not - because they can always consult their library's documentation to find
>> out for certain.
>
> Maybe the motivation for my request will clarify my reasoning
> regarding usability and testability.
>
> Recently I discovered that the VC-STL implementation of std::vector
> default constructor was changed to enable debugging feature in
> production code (i.e. "secure iterators") and now it can throw.
> Obviously it's possible to implement such feature without changing the
> no-fail guarantee that the implementation *always* use to have.
> Nevertheless I was informed that the standard doesn't forbid vector's
> default constructor from throwing so that code that *assumed* no-fail
> guarantee is anyway broken.
>
> I think that abusing the standard in such way is not fair

I think calling that "abuse of the standard" is an unfair
characterization.

> and hopefully clarifying the standard

I am sorry that you were surprised by this, but I think the standard
is perfectly clear on this point.  I agree that it could provide
stronger guarantees, and that making these guarantees would be useful.
I would even agree that as a matter of quality-of-implementation, that
particular implementation should never throw from its default
constructor, and in fact I'm very surprised to hear that it can.

> will make it easier to write correct, portable and testable code in
> respect to the standard itself and not specific implementation that
> might introduce breaking changes.
>
> IMHO, the fact that many operations never threw in practice gives
> good indication that they should have no-fail guarantee since
> otherwise the specifications might be exploitable by sloppy
> implementation without being accountable for breaking innocent
> clients claiming that such clients were always "broken".

They were, in terms of portability, "always broken."  It's no
different from relying on any other assumption that depends on a
particular C++ implementation.

Incidentally, if you want the other committee members (among the most
influential, the authors of that STL implementation to which you
refer) to be favorably disposed to a proposal strengthening
guarantees, it might be a good idea not to accuse them of standards
abuse.  While these particular guys have an admirable ability to
remain objective, everyone has his limits.

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: rani_sharoni@hotmail.com
Date: Tue, 16 Oct 2007 06:28:58 CST
Raw View
On Oct 15, 11:15 am, d...@boost-consulting.com (David Abrahams) wrote:
> on Sat Sep 22 2007, rani_sharoni-AT-hotmail.com wrote:
>
> > Nevertheless I was informed that the standard doesn't forbid vector's
> > default constructor from throwing so that code that *assumed* no-fail
> > guarantee is anyway broken.
>
> > I think that abusing the standard in such way is not fair
>
> I think calling that "abuse of the standard" is an unfair
> characterization.

I'll try to establish more positive attitude saying that the standard
is allowing high quality implementations though it can not guard
against poor quality. After reading your post about the
standardization process I adjusted my expectations from the standard
itself and I understand better how in practice quality is also
essential for usability.

> Incidentally, if you want the other committee members (among the most
> influential, the authors of that STL implementation to which you
> refer) to be favorably disposed to a proposal strengthening
> guarantees, it might be a good idea not to accuse them of standards
> abuse.  While these particular guys have an admirable ability to
> remain objective, everyone has his limits.

I actually have a strong impression that Plauger is not responsible
for the specific change that I mentioned. FWIW, after using very
aggressive fault injection to test the correctness of our error
handling code I must say that Plauger's implementation is remarkably
robust.

Thanks,
Rani

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: rani_sharoni@hotmail.com
Date: Sun, 23 Sep 2007 01:37:36 CST
Raw View
On Sep 21, 11:10 pm, gre...@pacbell.net (Greg Herlihy) wrote:
> So a C++ programmer does not have to
> wonder whether a particular Standard Library routine throws exceptions or
> not - because they can always consult their library's documentation to find
> out for certain.

Maybe the motivation for my request will clarify my reasoning
regarding usability and testability.

Recently I discovered that the VC-STL implementation of std::vector
default constructor was changed to enable debugging feature in
production code (i.e. "secure iterators") and now it can throw.
Obviously it's possible to implement such feature without changing the
no-fail guarantee that the implementation *always* use to have.
Nevertheless I was informed that the standard doesn't forbid vector's
default constructor from throwing so that code that *assumed* no-fail
guarantee is anyway broken.

I think that abusing the standard in such way is not fair and
hopefully clarifying the standard will make it easier to write
correct, portable and testable code in respect to the standard itself
and not specific implementation that might introduce breaking changes.

IMHO, the fact that many operations never threw in practice gives good
indication that they should have no-fail guarantee since otherwise the
specifications might be exploitable by sloppy implementation without
being accountable for breaking innocent clients claiming that such
clients were always "broken".

> then the vendor is obligated (according to 17.4.4.8/3) to
> document the type of exception thrown

I'm not sure how you got the impression that 17.4.4.8/3 says that the
implementation must specify the exceptions that it will throw when it
actually says that the implementation *might* refine the exception
specifications in conforming way:
An implementation *may* strengthen this implicit exception-
specification by adding an explicit one.

Thanks,
Rani

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =?iso-8859-1?q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Tue, 25 Sep 2007 11:02:37 CST
Raw View
On 22 Sep., 08:10, gre...@pacbell.net (Greg Herlihy) wrote:
> In case of VC++ (and I would guess every other C++ compiler), std::copy() does not throw
> exceptions, so the vendor is free to take advantage of that knowledge in the
> implementation of the other library routines.

Neither VC++ nor any other vendor that I'm aware of delivers
a standard library which does guarantee that std::copy does
not throw in any case. Of-course they usually provide specialized
version of std::copy that falls back to memmove, but not every
type compatible with std::copy is so, so there always remains
the most unspecific form which loops over assignments of the
form

*dest = *src;

That simply means that std::copy can fail for types, which's
assignment operator can throw.

> Of course it is impossible to test what would happen should std::copy() fail
> - if it is impossible for std::copy() to fail in the first place.

Disproved by above counter-example.

Greetings from Bremen,

Daniel Kr   gler


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: rani_sharoni@hotmail.com
Date: Sun, 16 Sep 2007 01:33:31 CST
Raw View
Hi,

I noticed that according to 17.4.4.8 any of the library's functions,
except for destructors, might throw unless specified.

OTOH, I don't see any exception specifications (via throw() or
wording) for functions that intuitively have no-fail guarantee.

I'm *not* referring to undefined behavior cases that anyway shouldn't
change the failure guarantee of given function (e.g.
vector::operator[] out of range access).

Here are some examples.

Non-mutating operations of containers: size(), empty() and find()
Iterators creation: begin(), end(), rbegin() and operations like
find()

For insertion on vector it's not clear whether the implementation is
allowed to throw if there is enough capacity and T is not throwing.
OTOH, it's explicitly specified that erase will not throw if T is not
throwing ("conditionally not-throw")

For vector::operator[] it's not clear that the operation as no fail
guarantee. Again, I'm not refereeing to the undefined behavior cases
due to pre-condition violations. Can operator[X] fail if X is in the
range? If so then there is probably a lot of broken code out there.

For basic_string (mainly string/wstring) I saw almost no exception
specifications. It's similar to vector and probably requires the same
clarifications.

Algorithm's where T and the operation can't throw, for example
for_each element do nothing.

Allowing the implementation too much freedom to throw will make
writing of correct failure-safe code practically impossible so I'm
quite sure that many of the above operations are intended to have no-
fail guarantee (sometime conditional).

I'll appreciate any comments.

Thanks,
Rani

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: David Abrahams <dave@boost-consulting.com>
Date: Sun, 16 Sep 2007 18:15:13 CST
Raw View
on Sun Sep 16 2007, rani_sharoni-AT-hotmail.com wrote:

> Hi,
>
> I noticed that according to 17.4.4.8 any of the library's functions,
> except for destructors, might throw unless specified.
>
> OTOH, I don't see any exception specifications (via throw() or
> wording) for functions that intuitively have no-fail guarantee.
>
> I'm *not* referring to undefined behavior cases that anyway shouldn't
> change the failure guarantee of given function (e.g.
> vector::operator[] out of range access).
>
> Here are some examples.
>
> Non-mutating operations of containers: size(), empty() and find()
> Iterators creation: begin(), end(), rbegin() and operations like
> find()

That's intentional.  Whether or not it's optimal is certainly open to
debate.  When we were adding the exception-safety language, giving
those functions a nothrow guarantee was not deemed essential to
writing exception-safe code, and we were in a period of finalization
where the actual number of words in any change to the standard was of
great concern to many members.  Larger proposals stood less chance of
being passed.  As it stands they only passed at the last minute, and
by the skin of their teeth, because a couple national bodies refused
to ratify the standard without them.

> For insertion on vector it's not clear whether the implementation is
> allowed to throw if there is enough capacity and T is not throwing.

Yes, it is.  Implementators don't need that leeway, but programmers
don't *need* the assurance either and at the time we were forced to
tilt strongly towards the implementors.

> OTOH, it's explicitly specified that erase will not throw if T is not
> throwing ("conditionally not-throw")

Good point.  But it *is* cheaper in words than a conditional nothrow
guarantee that depends on no reallocation.

> For vector::operator[] it's not clear that the operation as no fail
> guarantee. Again, I'm not refereeing to the undefined behavior cases
> due to pre-condition violations. Can operator[X] fail if X is in the
> range?

Nope.

Table 89: (Optional sequence container operations) states the
semantics (notwithstanding that the column is mislabelled) as

  *(a.begin() + n)

which isn't allowed to throw.

> If so then there is probably a lot of broken code out there.

Probably.

> For basic_string (mainly string/wstring) I saw almost no exception
> specifications.

Correct.

> It's similar to vector and probably requires the same
> clarifications.

I'm not sure it *requires* them.  FWIW it isn't a container,
officially, so the blanket guarantees that apply to containers don't
apply there and it would have been dangerous to try to add them.

> Algorithm's where T and the operation can't throw, for example
> for_each element do nothing.

Can't parse that, sorry.

> Allowing the implementation too much freedom to throw will make
> writing of correct failure-safe code practically impossible so I'm
> quite sure that many of the above operations are intended to have no-
> fail guarantee (sometime conditional).

The choices were very deliberate, if suboptimal.  It's probably a good
time to revisit them, though.

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

The Astoria Seminar ==> http://www.astoriaseminar.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: rani_sharoni@hotmail.com
Date: Sun, 16 Sep 2007 23:39:23 CST
Raw View
On Sep 16, 5:15 pm, David Abrahams <d...@boost-consulting.com> wrote:
> on Sun Sep 16 2007, rani_sharoni-AT-hotmail.com wrote:
>
> > I noticed that according to 17.4.4.8 any of the library's functions,
> > except for destructors, might throw unless specified.
>
> > OTOH, I don't see any exception specifications (via throw() or
> > wording) for functions that intuitively have no-fail guarantee.
>> [...]

> That's intentional.  Whether or not it's optimal is certainly open to
> debate.  When we were adding the exception-safety language, giving
> those functions a nothrow guarantee was not deemed essential to
> writing exception-safe code, and we were in a period of finalization
> where the actual number of words in any change to the standard was of
> great concern to many members.  Larger proposals stood less chance of
> being passed.  As it stands they only passed at the last minute, and
> by the skin of their teeth, because a couple national bodies refused
> to ratify the standard without them.

Nevertheless your accomplishment is groundbreaking.

I understand your point about essentiality but my concern is about
usability.
IMHO, assuming that such operations might fail is placing unreasonable
burden on the programmer and no implementation ever threw for them
hence if they'll start throwing the consequences might be disastrous
(and worst - silently).

BTW - I remember that you tested STL implementation using exhaustive
fault injection.
Did you actually fail such operations (e.g. container's non mutating
ones)?
Out of curiosity, is boost tested with fault injection?

> > Can operator[X] fail if X is in the range?
>
> Nope.
>
> Table 89: (Optional sequence container operations) states the
> semantics (notwithstanding that the column is mislabelled) as
>
>   *(a.begin() + n)
>
> which isn't allowed to throw.

I didn't see explicit no-fail specifications for a.begin() or
iterator::operator+.
Can you point me to such?

> > For basic_string (mainly string/wstring) I saw almost no exception
> > specifications.
>
> Correct.
>
> > It's similar to vector and probably requires the same
> > clarifications.
>
> I'm not sure it *requires* them.  FWIW it isn't a container,
> officially, so the blanket guarantees that apply to containers don't
> apply there and it would have been dangerous to try to add them.

I meant that string/wstring should also probably have explicit no-fail
specifications for some of its operations (e.g. non-mutating ones and
operator[]).

>> [...]
> Can't parse that, sorry.

Sorry for not being clear.
I didn't saw exception specifications for algorithms that have,
intuitively, no-fail guarantee for some instantiations. For example,
is for_each allowed to be implemented in away that it will throw for
every use-case (e.g. by internally allocating debugging related object
that might throw)?

> > Allowing the implementation too much freedom to throw will make
> > writing of correct failure-safe code practically impossible so I'm
> > quite sure that many of the above operations are intended to have no-
> > fail guarantee (sometime conditional).
>
> The choices were very deliberate, if suboptimal.  It's probably a good
> time to revisit them, though.

Some people already think that "no-fail iff throw()" not realizing
that it's impossible to program with such requirement so it's better
to clarify that.

I'll be happy to file a defect report based on this discussion.

Thanks,
Rani

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: dave@boost-consulting.com (David Abrahams)
Date: Tue, 18 Sep 2007 06:41:26 GMT
Raw View
on Mon Sep 17 2007, rani_sharoni-AT-hotmail.com wrote:

> On Sep 16, 5:15 pm, David Abrahams <d...@boost-consulting.com> wrote:
>> on Sun Sep 16 2007, rani_sharoni-AT-hotmail.com wrote:
>>
>> > I noticed that according to 17.4.4.8 any of the library's functions,
>> > except for destructors, might throw unless specified.
>>
>> > OTOH, I don't see any exception specifications (via throw() or
>> > wording) for functions that intuitively have no-fail guarantee.
>>> [...]
>
>> That's intentional.  Whether or not it's optimal is certainly open to
>> debate.  When we were adding the exception-safety language, giving
>> those functions a nothrow guarantee was not deemed essential to
>> writing exception-safe code, and we were in a period of finalization
>> where the actual number of words in any change to the standard was of
>> great concern to many members.  Larger proposals stood less chance of
>> being passed.  As it stands they only passed at the last minute, and
>> by the skin of their teeth, because a couple national bodies refused
>> to ratify the standard without them.
>
> Nevertheless your accomplishment is groundbreaking.
>
> I understand your point about essentiality but my concern is about
> usability.  IMHO, assuming that such operations might fail is
> placing unreasonable burden on the programmer and no implementation
> ever threw for them hence if they'll start throwing the consequences
> might be disastrous (and worst - silently).
>
> BTW - I remember that you tested STL implementation using exhaustive
> fault injection.

Yes.

> Did you actually fail such operations
> (e.g. container's non mutating ones)?

In my implementation atop STLPort, the restrictions were often tighter
than what we ended up specifying for the standard
(http://tinyurl.com/32elac) so things like operator[] were usually
specified not to fail and the tests would check for that.

> Out of curiosity, is boost tested with fault injection?

Maybe parts, but not the majority.

>> > Can operator[X] fail if X is in the range?
>>
>> Nope.
>>
>> Table 89: (Optional sequence container operations) states the
>> semantics (notwithstanding that the column is mislabelled) as
>>
>>   *(a.begin() + n)
>>
>> which isn't allowed to throw.
>
> I didn't see explicit no-fail specifications for a.begin() or
> iterator::operator+.
> Can you point me to such?

Wow, you're right.  No such guarantees exist.  I was thinking of
[container.requirements}:

  "no copy constructor or assignment operator of a returned iterator
  throws an exception."

>> > For basic_string (mainly string/wstring) I saw almost no exception
>> > specifications.
>>
>> Correct.
>>
>> > It's similar to vector and probably requires the same
>> > clarifications.
>>
>> I'm not sure it *requires* them.  FWIW it isn't a container,
>> officially, so the blanket guarantees that apply to containers don't
>> apply there and it would have been dangerous to try to add them.
>
> I meant that string/wstring should also probably have explicit
> no-fail specifications for some of its operations (e.g. non-mutating
> ones and operator[]).

I know what you meant.

>>> [...]
>> Can't parse that, sorry.
>
> Sorry for not being clear.
> I didn't saw exception specifications for algorithms that have,
> intuitively, no-fail guarantee for some instantiations. For example,
> is for_each allowed to be implemented in away that it will throw for
> every use-case (e.g. by internally allocating debugging related object
> that might throw)?

Yes.  :(

>> > Allowing the implementation too much freedom to throw will make
>> > writing of correct failure-safe code practically impossible so I'm
>> > quite sure that many of the above operations are intended to have no-
>> > fail guarantee (sometime conditional).
>>
>> The choices were very deliberate, if suboptimal.  It's probably a good
>> time to revisit them, though.
>
> Some people already think that "no-fail iff throw()" not realizing
> that it's impossible to program with such requirement so it's better
> to clarify that.

Oops; I lost you again.  If the standard says throw() it does mean the
operation can't fail.

> I'll be happy to file a defect report based on this discussion.

(Howard, please correct me if I'm wrong) I don't think it's
appropriate for a defect report, since we said exactly what we meant,
but I'd be happy to co-author a paper with you, proposing changes.

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

The Astoria Seminar ==> http://www.astoriaseminar.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: rani_sharoni@hotmail.com
Date: Thu, 20 Sep 2007 14:39:10 CST
Raw View
On Sep 17, 11:41 pm, d...@boost-consulting.com (David Abrahams) wrote:
> on Mon Sep 17 2007, rani_sharoni-AT-hotmail.com wrote:
>
> >> > I noticed that according to 17.4.4.8 any of the library's functions,
> >> > except for destructors, might throw unless specified.
>
> >> > OTOH, I don't see any exception specifications (via throw() or
> >> > wording) for functions that intuitively have no-fail guarantee.
> >>> [...]
>
> >> That's intentional.  Whether or not it's optimal is certainly open to
> >> debate.  When we were adding the exception-safety language, giving
> >> those functions a nothrow guarantee was not deemed essential to
> >> writing exception-safe code [...]
>
> > BTW - I remember that you tested STL implementation using exhaustive
> > fault injection.
>
> Yes.
>
> > Did you actually fail such operations
> > (e.g. container's non mutating ones)?
>
> In my implementation atop STLPort, the restrictions were often tighter
> than what we ended up specifying for the standard
> (http://tinyurl.com/32elac) so things like operator[] were usually
> specified not to fail and the tests would check for that.

Judging by the implementation of existing libraries (e.g. VC-STL) the
implementation itself relay of the fact that some of the "might-fail"
operations can't fail. For example, vector::erase uses std::copy which
means that the later is assumed not to throw if T's ctor is not
throwing.
That's perfectly valid from the implementation POV but makes it
impossible to test whether the application is strictly compliant for
which std::copy "might fail" even for non-throwing T.

I mentioned that above mainly to show in another way the importance of
reasonable specifications for the favor of usability and testability.

> > Out of curiosity, is boost tested with fault injection?
>
> Maybe parts, but not the majority.

I'm actually been practicing with non-intrusive fault injection tool
for a while and the effectiveness of the exhaustive technique is quite
remarkable.
I'll add to my task list item for running the boost test suite with
the tool. I'm sure that I'll find almost no issues but that will be
even better for advocating good programming ;-)

> > Some people already think that "no-fail iff throw()" not realizing
> > that it's impossible to program with such requirement so it's better
> > to clarify that.
>
> Oops; I lost you again.  If the standard says throw() it does mean the
> operation can't fail.

I meant that "no-fail if and only if (iff) throw()" is fundamentally
wrong (e.g. for conditional no-fail) but I already encountered people
that read the standard and got that wrong impression. Even in the
obviously direction (throw() implies no-fail) throw() is usually over
specifying compared with "undefined behavior" since it mandates
specific behavior that is hard to control from libraries and
suboptimal for compilers. In many cases the standard libraries
specifications actually seems to wisely avoid throw() for the favor of
wording (e.g. list::clear says "Throws: nothing").

> > I'll be happy to file a defect report based on this discussion.
>
> (Howard, please correct me if I'm wrong) I don't think it's
> appropriate for a defect report, since we said exactly what we meant,
> but I'd be happy to co-author a paper with you, proposing changes.

I thought that defect report is appropriate here since it's about
expectations for certain usability which is similar for the famous
"contiguous vector" DR.

I'll be more than happy to write a proposal with you.
It might also be worth it to consider adding suggestion for non
throwing default and move constructors of several containers and
that's also for the favor of usability since it doesn't seem to anyway
harm the implementation.

Thanks,
Rani

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: greghe@pacbell.net (Greg Herlihy)
Date: Sat, 22 Sep 2007 06:10:59 GMT
Raw View


On 9/20/07 1:39 PM, in article
1190304683.781001.318130@i38g2000prf.googlegroups.com,
"rani_sharoni@hotmail.com" <rani_sharoni@hotmail.com> wrote:

> On Sep 17, 11:41 pm, d...@boost-consulting.com (David Abrahams) wrote:
>>
>> In my implementation atop STLPort, the restrictions were often tighter
>> than what we ended up specifying for the standard
>> (http://tinyurl.com/32elac) so things like operator[] were usually
>> specified not to fail and the tests would check for that.
>
> Judging by the implementation of existing libraries (e.g. VC-STL) the
> implementation itself relay of the fact that some of the "might-fail"
> operations can't fail. For example, vector::erase uses std::copy which
> means that the later is assumed not to throw if T's ctor is not
> throwing.

No, the library vendor is not assuming anything about std::copy()'s throwing
behavior. Having written the routine in question, the library vendor is in a
pretty good position to know for sure whether their implementation of
std::copy() ever throws exceptions on its own - or not. In case of VC++ (and
I would guess every other C++ compiler), std::copy() does not throw
exceptions, so the vendor is free to take advantage of that knowledge in the
implementation of the other library routines. And clients of this vendor's
library may do the same.

After all, if a particular implementation of std::copy() does throw
exceptions, then the vendor is obligated (according to 17.4.4.8/3) to
document the type of exception thrown. So a C++ programmer does not have to
wonder whether a particular Standard Library routine throws exceptions or
not - because they can always consult their library's documentation to find
out for certain.

So the only effect of adding "no throw" clauses to existing Standard Library
functions would not be to provide any new information to C++ programmers.
Instead the only effect would be to inhibit the the discretion of library
vendors. If a library vendor goes to the trouble off having one of the
Standard Library routines throw an exception - then we can be fairly certain
that this behaior would be options (and would have to explicitly enabled by
the programmer) - and we can also be even more confident that the reason the
exception throwing behavior was added - was because a customer asked for it.

> That's perfectly valid from the implementation POV but makes it
> impossible to test whether the application is strictly compliant for
> which std::copy "might fail" even for non-throwing T.

Of course it is impossible to test what would happen should std::copy() fail
- if it is impossible for std::copy() to fail in the first place.

> I mentioned that above mainly to show in another way the importance of
> reasonable specifications for the favor of usability and testability.

But not apparently in favor of correctness. The "testability" of software is
not an end in its own right; if it were - then we would see more programmers
trying to maximize the number of potential points of failure in their
programs - just to be able to have a test for each of them. In reality,
correctness is the goal of software programming, testability is a goal only
insofar as the tests measure the correctness of the software.

>>> I'll be happy to file a defect report based on this discussion.
>>
>> (Howard, please correct me if I'm wrong) I don't think it's
>> appropriate for a defect report, since we said exactly what we meant,
>> but I'd be happy to co-author a paper with you, proposing changes.
>
> I thought that defect report is appropriate here since it's about
> expectations for certain usability which is similar for the famous
> "contiguous vector" DR.

There is no net gain to be realized simply by adding more throw clauses to
the Standard Library routines. Whatever the benefit (if any) of mandating a
particular behavior across implementations - is purchased at the vendors'
expense; the vendors would lose the latitude currently afforded them = they
would lose the freedom to exercise their own best judgment and to implement
whatever throw() behavior they deem best - both for themselves and for their
clients.

Greg

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]