This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: system_error::what
- From: Rodrigo Rivas <rodrigorivascosta at gmail dot com>
- To: libstdc++ at gcc dot gnu dot org
- Cc: Paolo Carlini <paolo dot carlini at oracle dot com>
- Date: Tue, 3 Aug 2010 15:27:46 +0200
- Subject: Re: system_error::what
- References: <AANLkTi=K2N8VwPAL2mnUhYMW8hP6ohuaAmc+RXWanCG5@mail.gmail.com> <4C57FCBD.6080103@oracle.com>
> Anyway, before any further details, do you have a Copyright assignment
> in place? It's a requirement for contributions more than 5-10 lines long.
No, I don't. But I am willing to to have it for all future changes if
you can point me how to do it.
> Well, I wish we can figure out a better strategy for this, because as-is it
> obviously breaks the binary compatibility with existing C++0x binaries
> already using system_error, due to the added string member.
Oh... right. You could build the error string when passing it to the
"runtime_error" constructor, then the inherited what() would just
work.
But the problem is that the contents of the string depends on the
_M_code.message(), and _M_code is not yet constructed!
Unless... we add an undocumented protected function to runtime_error
that changes the message "after" construction (hey, it may be useful
elsewhere). Something like:
class runtime_error : public exception
{
string _M_msg;
protected:
/* for internal use only */
void __set_msg(const string &__msg)
{ _M_msg = __msg; }
public:
...
};
class system_error : runtime_error
{
private:
void __set_runtime_error_msg()
{
try {
string __re;
__re = runtime_error::what();
if (!__re.empty())
__re += ": ";
__re += _M_code.message();
__set_msg(__re);
}
catch (...) {
}
}
public:
system_error(int __v, const error_category& __ecat, const char *__what)
: runtime_error(__what), _M_code(error_code(__v, __ecat))
{
__set_runtime_error_msg();
}
/* The same with the other constructors */
};
I think that will not break the ABI.
Or maybe, since this is C++0x only, we can rely on constructor
delegation once it is ready in the language:
class system_error : runtime_error
{
private:
...
static string __make_error_msg(const error_code &__ec, const string &__what)
{
// do the thing
}
public:
system_error(error_code __ec, const string &__what)
: runtime_error( __make_error_msg(__ec, __what)), _M_code(__ec) { }
system_error(int __v, const error_category& __ecat, const string &__what)
: system_error(error_code(__v, __ecat), __what) { } //delegate!
/* The same with the other constructors */
};
But I don't know if this affects binary compatibility (constructors
are quite mysterious to me).
Until constructor delegation is ready we can copy/paste the relevant
code in all the constructors, with temporary error_code values where
needed.
Anyway, for what is worth, boost::system_error resolves as my original patch.
Comments?
Regards.
--
Rodrigo.