Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<exception>: std::exception::what has wrong signature #948

Open
AlexGuteniev opened this issue Jul 1, 2020 · 9 comments
Open

<exception>: std::exception::what has wrong signature #948

AlexGuteniev opened this issue Jul 1, 2020 · 9 comments
Labels
bug Something isn't working

Comments

@AlexGuteniev
Copy link
Contributor

AlexGuteniev commented Jul 1, 2020

Describe the bug
std::exception::what is not noexcept.
See also #882 - should probably be fixed together. #808 is also in similar area

Command-line test case


d:\Temp2>type repro.cpp
#include <cstdio>
#include <exception>

int main()
{
    auto b = noexcept(std::exception{}.what());
    std::printf("%d\n", (int)b);
}


d:\Temp2>cl /EHsc /permissive- /std:c++latest /Zc:__cplusplus /Zc:externConstexpr repro.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.27.29009.1 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

/std:c++latest is provided as a preview of language features from the latest C++
working draft, and we're eager to hear about bugs and suggestions for improvements.
However, note that these features are provided as-is without support, and subject
to changes or removal as the working draft evolves. See
https://go.microsoft.com/fwlink/?linkid=2045807 for details.

repro.cpp
Microsoft (R) Incremental Linker Version 14.27.29009.1
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:repro.exe
repro.obj

d:\Temp2>.\repro.exe
0

Expected behavior
Should print 1 as ctor is noexcept.

STL version

Microsoft Visual Studio Professional 2019 Preview
Version 16.7.0 Preview 3.1

Additional context
This item is also tracked on Developer Community as DevCom-785027 and by Microsoft-internal VSO-1006425 / AB#1006425.

vNext note: Resolving this issue will require breaking binary compatibility. We won't be able to accept pull requests for this issue until the vNext branch is available. See #169 for more information.

@StephanTLavavej StephanTLavavej changed the title <exception>: VC++: std::exception::what has wrong signature <exception>: std::exception::what has wrong signature Jul 1, 2020
@StephanTLavavej StephanTLavavej added bug Something isn't working vNext Breaks binary compatibility labels Jul 1, 2020
@StephanTLavavej
Copy link
Member

Thanks, I've linked the Microsoft-internal bug to this issue. This is a rare example of a vNext bug where the bincompat break isn't nearly as bad as the source-compat break (as it breaks every pre-noexcept override of what()).

@StephanTLavavej
Copy link
Member

After thinking about this again, I suspect that this is not actually ABI-breaking, but the source-breaking change is indeed severe and I still don't know how to logistically go about doing this: https://godbolt.org/z/PjEnhxdjW

We could explore guarding the change for C++23, so only /std:c++latest compilations would encounter breaks, but we'd still have to go report/fix/workaround a whole bunch of problems in the Real World Code test suite, MSVC and VS, Office, Windows, etc. Even with an escape hatch I'm not very eager to explore this. vNext doesn't technically make this any easier to do, except that it'll likely be filled with other source-compat breaks.

@CaseyCarter
Copy link
Contributor

Is it time for us to have our first /permissive--only library "conformance improvement"? People use /permissive- because they want to write standard-conforming code, they are likely willing to add a few noexcepts. Note that a noexcept function can override a non-noexcept signature (https://godbolt.org/z/ocd4zWdYb), so libraries with noexcept will continue to work in permissive mode. I feel like gating this behind /permissive- (probably still with an escape hatch) is consistent with how the compiler has been handling breaking conformance improvements for the last 8 years. (I do think we want a reliable mechanism to determine whether the compiler is in permissive or strict mode for this, the hack we use for tests is fine for tests but feels brittle to rely on for production.)

There doesn't seem to be a technical reason to put this off. We know we want to be conformant eventually, it feels like we're waiting for a "good time" to do this that's never going to appear.

@StephanTLavavej
Copy link
Member

It would still be a lot of work to clean up RWC but /permissive- does feel right for this.

(I see how we could use our hack to apply noexcept to the signature, but it would be gross and having a macro to finally sense the mode would be better.)

@diablodale
Copy link

I suggest a visit to this STL project's stated mission, goals, and non-goals to help in this discussion...

  • Mission and reason-to-exist is "ships as part of the MSVC toolset". It is clearly stated, first sentence.
  • Goal 1 is conformance. what() is not.
  • Goal 4 is compatibility. There is consensus ABI is not involved. A subset of legacy code source compatibility is involved. Goal 4 writes "We consider source compatibility to be important, but not all-important; breaking source compatibility can be an acceptable cost if done for the right reasons in the right way (e.g. in a controlled manner with escape hatches)."
  • Non-goal 2: Adding non-Standard extensions. what() is non-standard and porting the non-standard what() to each update 17/20/23... is adding it over and over.

Nowhere is it stated this project's goal is to consider private internal needs of other Microsoft divisions (MSVC and VS, Office, Windows, etc). Someone somewhere in Microsoft might question the P&L of correcting what() because it will burn some resources to fix or toggle-switch their non-compliant code. But that's simply not of concern to me and (if polled) a measurable group of other ISVs.

🤔Am I reading correctly that the source-breaking behavior is primarily when code derives from what/exceptions?
🤔And that code that doesn't derive (like below) would not be affected and instead be better...it would compile cleanly like gcc and clang do already.

void myfunc() noexcept {
  try {
    // do work
    throw std::exception("my text");
  }
  catch (const std::exception& err) {
    printf("%s", err.what());
  }
}

If both 🤔 are true, then I suggest breaking a subset of old code's what(). And if you want to reduce complaints from old code, then put old non-compliant behavior in a switch. Make the non-compliant code be required to apply the switch. By default...should be compliant. This approach is alignment with all four mission+goal bullets I list at the top.

@AlexGuteniev
Copy link
Contributor Author

Since it is no longer vNext, what would be the strategy to fix it?

@TheStormN
Copy link
Contributor

My proposal(as this is only source breaking thing) is to make a preprocessor define(documented), which people would be able to use to restore the non-conforming behavior so the migration would be less noisy.

@cpplearner
Copy link
Contributor

cpplearner commented Aug 2, 2024

My proposal(as this is only source breaking thing) is to make a preprocessor define(documented), which people would be able to use to restore the non-conforming behavior so the migration would be less noisy.

That's the "escape hatch" that Stephan mentioned in #948 (comment)

@TheStormN
Copy link
Contributor

@cpplearner Sorry, not sure how I missed that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants