HowardHinnant / date

A date and time library based on the C++11/14/17 <chrono> header
Other
3.11k stars 671 forks source link

warning STL4006: std::uncaught_exception() is deprecated in C++17 #474

Open degski opened 5 years ago

degski commented 5 years ago
y:\vcpkg\installed\x64-windows-static\include\date\date.h(1050,1): warning C4996:  'std::uncaught_exception': warning STL4006: std::uncaught_exception() is deprecated in C++17. It is superseded by std::uncaught_exceptions(), plural.
You can define _SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received this warning.
HowardHinnant commented 5 years ago

You can also disable this warning by defining HAS_UNCAUGHT_EXCEPTIONS=1.

degski commented 5 years ago

Thanks Howard.

degski commented 5 years ago

HAS_UNCAUGHT_EXCEPTIONS=1 would be a useful addition to the readme.md.

But I see that the library defines in date.h:97:

#if defined(_MSC_VER) && (!defined(__clang__) || (_MSC_VER < 1910))
// MSVC
#  define _SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING
...

This means that these warning potentially get suppressed in places I would like to have these warnings. The macro should be undefined at the end of the header, if and when the macro was not defined in the first place. Something like:

#if !defined(_SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING)
#define _SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING
#define DATE_UNDEF_SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING 
#endif

....

// at the end.
#if defined (DATE_UNDEF_SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING) 
#undef _SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING
#undef DATE_UNDEF_SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING 
#endif

I'm not sure about the !defined(__clang__), with clang-cl, both _MSC_VER and __clang__ are defined, while clang-cl uses the same STL-implementation as MSVC.

grainrigi commented 5 years ago

HAS_UNCAUGHT_EXCEPTION is defined as below:

#ifndef HAS_UNCAUGHT_EXCEPTIONS
#  if __cplusplus > 201703 // <- excludes C++17
#    define HAS_UNCAUGHT_EXCEPTIONS 1
#  else
#    define HAS_UNCAUGHT_EXCEPTIONS 0
#  endif
#endif  // HAS_UNCAUGHT_EXCEPTIONS

As shown above, C++17 is excluded although C++17 has std::uncaught_exceptions. Is this the intended behavior?

HowardHinnant commented 5 years ago

Yes. The intent is to use the old API until it is removed in C++20. The rationale is that even though some clients are compiling with C++17, they may be targeting platforms (e.g. older OS's) which do not ship the newer std::uncaught_exceptions.

This is definitely a compromise and there's no way to make everyone happy on it. So the programmer can override this default behavior by setting HAS_UNCAUGHT_EXCEPTIONS on the command line.

lingfors commented 4 years ago

It seems weird to me to not enable a new feature if it is available, and instead use an old feature that is deprecated by default. Imho, the default behavior should be to use the new feature by default, and allow the user to override it if she wants to use the old deprecated feature.

HowardHinnant commented 4 years ago

I know.