C++ Logo

sg16

Advanced search

Re: [isocpp-sg16] first draft of wording mandating literal encoding for result of .what() during constant evaluation

From: Tom Honermann <tom_at_[hidden]>
Date: Tue, 13 Aug 2024 18:05:53 -0400
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
<http://eel.is/c++draft/alloc.errors#bad.alloc-2>.

    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 <http://eel.is/c++draft/exception#2>
(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]
    <http://eel.is/c++draft/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)
>
>
>

Received on 2024-08-13 22:05:58