doctest / doctest

The fastest feature-rich C++11/14/17/20/23 single-header testing framework
https://bit.ly/doctest-docs
MIT License
5.9k stars 643 forks source link

C++20 removed std::uncaught_exception #333

Closed StephanTLavavej closed 4 years ago

StephanTLavavej commented 4 years ago

std::uncaught_exception was deprecated in C++17 and removed in C++20. Section [diff.cpp17.depr]/1 of the C++20 Working Draft explains:

Change: Remove uncaught_­exception. Rationale: The function did not have a clear specification when multiple exceptions were active, and has been superseded by uncaught_­exceptions. Effect on original feature: A valid C++ 2017 program that calls std​::​uncaught_­exception may fail to compile. It might be revised to use std​::​uncaught_­exceptions instead, for clear and portable semantics.

This function is being used here:

https://github.com/onqtam/doctest/blob/503de03ee2cbbfc58c2063dce36dc96f917f2da3/doctest/parts/doctest.cpp#L929-L939

https://github.com/onqtam/doctest/blob/503de03ee2cbbfc58c2063dce36dc96f917f2da3/doctest/parts/doctest.cpp#L1273-L1280

And similarly in doctest/doctest.h (which appears to be auto-generated).

Now that MSVC's STL has merged https://github.com/microsoft/STL/pull/380, doctest will fail to compile in /std:c++latest mode with VS 2019 16.6 Preview 2 (not yet released).

We (the MSVC team) are seeing this because we test a number of open-source projects with development builds of the MSVC toolset. (We encountered this case via https://github.com/lewissbaker/cppcoro/blob/master/test/doctest/doctest.h .) This allows us to find and fix bugs in our toolset before they can affect you, and it also allows us to provide advance notice of source-breaking incompatibilities like this one.

MSVC provides "escape hatch" macros that can be defined project-wide to suppress the deprecation warning and restore the removed type trait. (Specifically, compiling with /D_SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING and /D_HAS_DEPRECATED_UNCAUGHT_EXCEPTION=1.)

However, libraries like doctest don't have control over their programmer-users' project-wide settings, so global escape hatches aren't feasible. As you've discovered, the deprecation warning can be locally silenced by push-disable-popping warning C4996, but the removal can't be locally restored. Therefore, the deprecated/removed machinery should be entirely avoided if possible.

Fortunately, a Standard feature-test macro is available to detect when the replacement std::uncaught_exceptions (plural) can be called. You can activate that based on #ifdef __cpp_lib_uncaught_exceptions and otherwise fall back to the older function. This will allow doctest to work in all language modes.

onqtam commented 4 years ago

Thanks for the report and sorry for the delay - I just merged #340 (thanks to @cyyever) and will soon publish a new official version!

StephanTLavavej commented 4 years ago

Yay, thank you!