This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug libstdc++/10093] Regression: Setting failbit in exceptions doesn't work
- From: "sebor at roguewave dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 24 Jul 2003 17:08:16 -0000
- Subject: [Bug libstdc++/10093] Regression: Setting failbit in exceptions doesn't work
- References: <20030315103601.10093.peturr02@ru.is>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10093
------- Additional Comments From sebor at roguewave dot com 2003-07-24 17:08 -------
Subject: Re: Regression: Setting failbit in exceptions
doesn't work
peturr02 at ru dot is wrote:
> ------- Additional Comments From peturr02 at ru dot is 2003-07-24 15:47 -------
> Martin Sebor wrote:
>
>>My feeling is that if setstate() should end up throwing an exception
>>some exception should always propagate out of the calling function.
>
>
> I would like to agree, but the current proposed resolution and rationale
> for DR 309 says otherwise:
>
> The LWG feels that no clarification of EH policy is necessary: the
> standard is precise about which operations sentry's constructor
> performs, and about which of those operations can throw.
What DR is this again? I don't see this in the still open
issue 309:
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#309
>
> In other words, the description of the sentry constructor has been
> declared to be *clear* and *precise*. Since the description is
> precise, and it does not say that the sentry::sentry() catches
> exceptions, I assume this means that it should not catch any
> exceptions.
309 proposes that the sentry ctor set badbit if it catches
an exception during input, and that the caught exception be
rethrown when (badbit & exceptions()) is non-zero.
>
> The problem is that sentry::sentry() performs input (calls
> rdbuf()->sgetc() and/or rdbuf()->sbumpc()) and operator>> is
> supposed to catch those exceptions
That's not my understanding. Here's how I would implement
operator>>() (which is also what our library does, even
though the code might look different):
operator>>(int &x)
{
sentry guard (*this);
if (guard) {
iostate err;
try {
use_facet<num_get<charT> >(getloc ())
.get (..., *this, err, x);
}
catch (...) {
bool rethrow;
try {
setstate (badbit);
rethrow = false;
}
catch (...) {
rethrow = true;
}
if (rethrow)
throw;
}
if (err)
setstate (err);
}
}
> - which means it must catch all
> exceptions thrown by sentry::sentry(), including those thrown by
> setstate(). I don't think it would make sense to treat exceptions
> thrown by setstate() differently based on whether setstate() was
> called directly by operator>> or indirectly through sentry::sentry(),
> so operator>> should catch exceptions thrown from setstate().
That's why sentry must catch exceptions, and that's also
why you can't implement the function above as
operator>>(int &x)
{
try {
sentry guard (*this);
...
}
catch (...) {
bool rethrow;
try {
setstate (badbit);
...
Because such an implementation would end up setting badbit
if sentry threw failbit. I'm sure you agree that's not what
should happen.
>
> However, if this is the intended meaning, then we have a potential
> DR: The description of badbit in 27.4.2.1.3 is incomplete and the
> words "or (exceptions() & failbit) != 0" need to be added.
I don't think this could ever pass. The intent of badbit is
to indicate some unrecoverable error in the stream buffer.
Setting it as a result of failbit being set in both state
and exceptions would defeat the purpose of the bit.
If there is a defect in there somewhere (I don't doubt there
is), it's in the imprecise wording possibly even muddied by
a number of fixes that went into the TC, not in the intent.
Martin