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)
>
>
>
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