Oh my. I somehow failed to read the last sentence of what I quoted. You are absolutely right.
It might be worth adding a drafting note that references [exception]p2 to
point out that the proposed addition imposes requirements on
derived types defined by the standard library.
Tom.
I'm vaguely remembered Jens saying during the meeting that it will be ok to just put it to std::exception, that's what I did.
I think the http://eel.is/c++draft/exception#2 "The what() member function of each such T satisfies the constraints specified for exception::what() (see below)."
and having the added text to https://eel.is/c++draft/exception#5 "Returns: An implementation-defined ntbs, which during constant evaluation shall be encoded with the ordinary literal encoding ([lex.ccon])."
Is enough, as all inherited type from std::exception must satisfy constraints of std::exception::what() which is what I specified.
Hana
On 14. 8. 2024, at 0:05, Tom Honermann <tom@honermann.net> wrote:
I don't think this wording works particularly well. The proposed change is only applicable to the implementation of std::exception::what(); it doesn't impose requirements on the implementations in derived classes. Consider the following example:
#include <exception>
#include <iostream>
constexpr int f() {
try {
throw std::bad_alloc();
} catch (std::exception &e) {
std::cout << e.what() << "\n";
}
return 0;
}
int main() {
constexpr int i = f();
}The implementation of std::exception::what() isn't invoked in this case. The applicable wording is therefore [bad.alloc]p2.
const char* what() const noexcept override;
Returns: An implementation-defined NTBS.
I think the new requirement for behavior during constant evaluation needs to be applied individually to each of the what() specifications for exception, bad_exception, bad_alloc, bad_array_new_length, bad_cast, and bad_typeid.
Alternatively, since it has not previously been possible to define a constexpr type derived from std::exception, we could consider adding some blanket wording that does impose requirements on derived classes. There is precedent in [exception]p2 (emphasis mine):
Except where explicitly specified otherwise, each standard library class T that derives from class exception has the following publicly accessible member functions, each of them having a non-throwing exception specification ([except.spec]):
- default constructor (unless the class synopsis shows other constructors)
- copy constructor
- copy assignment operator
The copy constructor and the copy assignment operator meet the following postcondition: If two objects lhs and rhs both have dynamic type T and lhs is a copy of rhs, then strcmp(lhs.what(), rhs.what()) is equal to 0. The what() member function of each such T satisfies the constraints specified for exception::what() (see below).
I think it would be reasonable to amend this paragraph to impose the encoding requirement on standard library classes that are usable during constant evaluation.
Tom.
On 7/31/24 5:21 PM, Hana Dusíková via SG16 wrote:
I'm sending an attachment with first draft for R4 containing change discussed today in SG16. I would like all the feedback and help you can give.
Thanks!Hana
PS: If you don't care about persistence the change is also here: https://isocpp.org/files/papers/D3068R4.html#literal-encoding (link leading directly to the change)