microsoft / STL

MSVC's implementation of the C++ Standard Library.
Other
10.05k stars 1.48k forks source link

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

Open AlexGuteniev opened 4 years ago

AlexGuteniev commented 4 years ago

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 commented 4 years ago

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 commented 10 months ago

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 commented 10 months ago

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 commented 10 months ago

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 commented 10 months ago

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

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 commented 1 month ago

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

TheStormN commented 1 month ago

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 commented 1 month ago

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 https://github.com/microsoft/STL/issues/948#issuecomment-1785057335

TheStormN commented 1 month ago

@cpplearner Sorry, not sure how I missed that.