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.

On 8/13/24 6:21 PM, Hana Dusíková wrote:
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)