Movatterモバイル変換


[0]ホーム

URL:



This page is a snapshot from the LWG issues list, see theLibrary Active Issues List for more information and the meaning ofC++11 status.

1103.system_error constructor postcondition overly strict

Section: 19.5.8.2[syserr.syserr.members]Status:C++11Submitter: Howard HinnantOpened: 2009-04-25Last modified: 2016-01-28

Priority:Not Prioritized

View all otherissues in [syserr.syserr.members].

View all issues withC++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 classsystem_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 bothconformance, and the desired intent in thewhat() string, thesystem_error constructor must store "In FooBar" in the base class,and then form the desired output each timewhat() is called. Oralternatively, store "In FooBar" in the base class, and store the desiredwhat() string in the derivedsystem_error, and overridewhat() to return the string in the derived part.

Both of the above implementations seem suboptimal to me. In one I'm computinga new string every timewhat() is called. And sincewhat()can't propagate exceptions, the client may get a different string on differentcalls.

The second solution requires storing two strings instead of one.

What I would like to be able to do is form the desiredwhat() stringonce in thesystem_error constructor, and storethat in thebase class. Now I'm:

  1. Computing the desiredwhat() only once.
  2. The base classwhat() definition is sufficient and nothrow.
  3. I'm not storing multiple strings.

This is smaller code, smaller data, and faster.

ios_base::failure has the same issue.

[Comments about this change received favorable comments from thesystem_errordesigners.]

[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() == ecandstrcmp(runtime_error::what(), what_arg.c_str()) == 0string(what()).find(what_arg) != string::npos.

system_error(error_code ec, const char* what_arg);

-4-Postconditions:code() == ecandstrcmp(runtime_error::what(), what_arg) == 0string(what()).find(what_arg) != string::npos.

system_error(error_code ec);

-6-Postconditions:code() == ecandstrcmp(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()) == 0string(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) == 0string(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 ofwhat():

const char *what() const throw();

-14-Returns: An NTBS incorporatingruntime_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 classfailureby 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 classfailureby constructing the base class withmsg andec.

-6-Postcondition:code() == ec and strcmp(what(), msg) == 0

In [ios::failure], removewhat (the base class definitionneed not be repeated here).

const char* what() const;

-7-Returns: The messagemsg with which the exception was created.


[8]ページ先頭

©2009-2026 Movatter.jp