You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
<exception>: constructor does not copy what_arg if _HAS_EXCEPTIONS=0 #2114
The example comes from https://github.com/nlohmann/json where exceptions are created by a SAX parser, but it is up to the client whether they are thrown or not. Therefore, using exception classes while disabling throwing exceptions is a usecase.
Expected behavior
The exception makes a copy of the what_arg argument, regardless of the value of _HAS_EXCEPTIONS.
STL version
I could reproduce the issue with MSVC 19.16.27045.0 and MSVC 19.29.30040.0.
_HAS_EXCEPTIONS=0 is quasi-supported (it's not officially documented, and has various design/usability issues like this one, although we've tried to avoid breaking how it works). I've marked this as vNext because I believe that dynamically allocating/deallocating memory in the _HAS_EXCEPTIONS=0 implementation of exception would be ABI-breaking. Also marked as decision needed - as Miya Natsuhara (@mnatsuhara) mentioned, we need to decide whether to change this long-standing behavior (e.g. attempting to malloc memory, and storing a string literal as a fallback if we're unable to; that would also require storing whether the string is dynamically allocated, which is super-definitely ABI breaking).
Finally, Casey Carter (@CaseyCarter) reminded me that this constructor itself is non-Standard (this applies to the normal _HAS_EXCEPTIONS=1 implementation too) - that's tracked by #882.
About the non-standard issue: I think it's not about the constructor of std::exception, but rather about the behavior of the derived classes like runtime_error(const char* what_arg) - there I would still expect a copy of the argument to be made.
About the non-standard issue: I think it's not about the constructor of std::exception, but rather about the behavior of the derived classes like runtime_error(const char* what_arg) - there I would still expect a copy of the argument to be made.
Ah, I see - thanks for the clarification. It hadn't occurred to me the the standard constructors in the derived classes are implemented in terms of this non-standard constructor in exception.
We talked about this at the weekly maintainer meeting and we believe that in the _HAS_EXCEPTIONS=0 case we should do what we do for _HAS_EXCEPTIONS=1: try to copy the string, and if we can't allocate memory, then just store nothing. (Separately we should get rid of that non-Standard base class constructor although doing so will be an epic undertaking.)
changed the title [-]<exception>: constructor does not copy what_arg if _HAS_EXCEPTIONS=0[/-][+]`<exception>`: constructor does not copy what_arg if `_HAS_EXCEPTIONS=0`[/+]on Dec 18, 2024
Activity
StephanTLavavej commentedon Aug 11, 2021
_HAS_EXCEPTIONS=0is quasi-supported (it's not officially documented, and has various design/usability issues like this one, although we've tried to avoid breaking how it works). I've marked this asvNextbecause I believe that dynamically allocating/deallocating memory in the_HAS_EXCEPTIONS=0implementation ofexceptionwould be ABI-breaking. Also marked asdecision needed- as Miya Natsuhara (@mnatsuhara) mentioned, we need to decide whether to change this long-standing behavior (e.g. attempting tomallocmemory, and storing a string literal as a fallback if we're unable to; that would also require storing whether the string is dynamically allocated, which is super-definitely ABI breaking).Finally, Casey Carter (@CaseyCarter) reminded me that this constructor itself is non-Standard (this applies to the normal
_HAS_EXCEPTIONS=1implementation too) - that's tracked by #882.nlohmann commentedon Aug 12, 2021
Thanks for the quick response!
About the non-standard issue: I think it's not about the constructor of
std::exception, but rather about the behavior of the derived classes likeruntime_error(const char* what_arg)- there I would still expect a copy of the argument to be made.CaseyCarter commentedon Aug 12, 2021
Ah, I see - thanks for the clarification. It hadn't occurred to me the the standard constructors in the derived classes are implemented in terms of this non-standard constructor in
exception.StephanTLavavej commentedon Apr 19, 2023
We talked about this at the weekly maintainer meeting and we believe that in the
_HAS_EXCEPTIONS=0case we should do what we do for_HAS_EXCEPTIONS=1: try to copy the string, and if we can't allocate memory, then just store nothing. (Separately we should get rid of that non-Standard base class constructor although doing so will be an epic undertaking.)[-]<exception>: constructor does not copy what_arg if _HAS_EXCEPTIONS=0[/-][+]`<exception>`: constructor does not copy what_arg if `_HAS_EXCEPTIONS=0`[/+]StephanTLavavej commentedon Nov 12, 2025
Related: #5406 fixed #5276.
kleisauke commentedon Jan 22, 2026
FWIW, there's a much simpler test case here: nodejs/node-addon-api#85 (comment).