This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++11 status.
1103.system_error
constructor postcondition overly strict
Section: 19.5.8.2 [syserr.syserr.members] Status: C++11 Submitter: Howard Hinnant Opened: 2009-04-25 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [syserr.syserr.members].
View all issues with C++11 status.
Discussion:
19.5.8.2 [syserr.syserr.members] says:
system_error(error_code ec, const string& what_arg);Effects: Constructs an object of class
system_error
.Postconditions:
code() == ec
andstrcmp(runtime_error::what(), what_arg.c_str()) == 0
.
However the intent is for:
std::system_error se(std::errc::not_a_directory, "In FooBar"); ... se.what(); // returns something along the lines of: // "In FooBar: Not a directory"
The way the constructor postconditions are set up now, to achieve both conformance, and the desired intent in the what()
string, the system_error
constructor must store "In FooBar" in the base class, and then form the desired output each time what()
is called. Or alternatively, store "In FooBar" in the base class, and store the desired what()
string in the derived system_error
, and override what()
to return the string in the derived part.
Both of the above implementations seem suboptimal to me. In one I'm computing a new string every time what()
is called. And since what()
can't propagate exceptions, the client may get a different string on different calls.
The second solution requires storing two strings instead of one.
What I would like to be able to do is form the desired what()
string once in the system_error
constructor, and store that in the base class. Now I'm:
what()
only once.what()
definition is sufficient and nothrow.This is smaller code, smaller data, and faster.
ios_base::failure
has the same issue.
[ Comments about this change received favorable comments from the system_error
designers. ]
[ Batavia (2009-05): ]
We agree with the proposed resolution.
Move to Tentatively Ready.
Proposed resolution:
In 19.5.8.2 [syserr.syserr.members], change the following constructor postconditions:
system_error(error_code ec, const string& what_arg);-2- Postconditions:
code() == ec
andstrcmp(runtime_error::what(), what_arg.c_str()) == 0 string(what()).find(what_arg) != string::npos
.system_error(error_code ec, const char* what_arg);-4- Postconditions:
code() == ec
andstrcmp(runtime_error::what(), what_arg) == 0 string(what()).find(what_arg) != string::npos
.system_error(error_code ec);-6- Postconditions:
code() == ec
andstrcmp(runtime_error::what(), ""
.system_error(int ev, const error_category& ecat, const string& what_arg);-8- Postconditions:
code() == error_code(ev, ecat)
andstrcmp(runtime_error::what(), what_arg.c_str()) == 0 string(what()).find(what_arg) != string::npos
.system_error(int ev, const error_category& ecat, const char* what_arg);-10- Postconditions:
code() == error_code(ev, ecat)
andstrcmp(runtime_error::what(), what_arg) == 0 string(what()).find(what_arg) != string::npos
.system_error(int ev, const error_category& ecat);-12- Postconditions:
code() == error_code(ev, ecat)
andstrcmp(runtime_error::what(), "") == 0
.
In 19.5.8.2 [syserr.syserr.members], change the description of what()
:
const char *what() const throw();-14- Returns: An NTBS incorporating
runtime_error::what()
andcode().message()
the arguments supplied in the constructor.[Note: One possible implementation would be: The return NTBS might take the form:
what_arg + ": " + code().message()
if (msg.empty()) { try { string tmp = runtime_error::what(); if (code()) { if (!tmp.empty()) tmp += ": "; tmp += code().message(); } swap(msg, tmp); } catch(...) { return runtime_error::what(); } return msg.c_str();— end note]
In [ios::failure], change the synopsis:
namespace std { class ios_base::failure : public system_error { public: explicit failure(const string& msg, const error_code& ec = io_errc::stream); explicit failure(const char* msg, const error_code& ec = io_errc::stream); virtual const char* what() const throw(); }; }
In [ios::failure], change the description of the constructors:
explicit failure(const string& msg, , const error_code& ec = io_errc::stream);-3- Effects: Constructs an object of class
failure
by constructing the base class withmsg
andec
.-4- Postcondition:
code() == ec
andstrcmp(what(), msg.c_str()) == 0
explicit failure(const char* msg, const error_code& ec = io_errc::stream);-5- Effects: Constructs an object of class
failure
by constructing the base class withmsg
andec
.-6- Postcondition:
code() == ec and strcmp(what(), msg) == 0
In [ios::failure], remove what
(the base class definition need not be repeated here).
const char* what() const;-7- Returns: The message
msg
with which the exception was created.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4