According to https://en.cppreference.com/w/c/chrono/localtime C11 added
optional gmtime_s() and localtime_s() which conflict with the long
standing MSVCRT/UCRT variants. I have no idea why they did this (C23
finally adds the traditional *_r() functions which are IIRC older than
POSIX).
The attached patch provides the C11 variants if __STDC_WANT_LIB_EXT1__
is defined.
All 3 alternatives of the example below result in the same assembly code:
#define __STDC_WANT_LIB_EXT1__ 1
#include <time.h>
struct tm * localtime_chaos(const time_t * t, struct tm * tb)
{
#if __STDC_LIB_EXT1__ // C11, optional, requires __STDC_WANT_LIB_EXT1__
return localtime_s(t, tb);
#elif defined(_POSIX_THREAD_SAFE_FUNCTIONS)
return localtime_r(t, tb);
#elif defined(_WIN32) // assume MSVCRT/UCRT
return (!localtime_s(tb, t) ? tb : 0);
#else
#error giving up ...
#endif
}
--
Regards,
Christian
From fbcdb908526f31c8872f5e639af87a26187eab10 Mon Sep 17 00:00:00 2001
From: Christian Franke <[email protected]>
Date: Sat, 15 Jul 2023 18:42:42 +0200
Subject: [PATCH] headers: Add C11 variants of gmtime_s and localtime_s
Enable these only if __STDC_WANT_LIB_EXT1__ is defined to nonzero.
Then define __STDC_LIB_EXT1__ to indicate availability and hide
the incompatible MSVCRT/UCRT variants for C code.
Provide both variants for C++ code.
Signed-off-by: Christian Franke <[email protected]>
---
mingw-w64-headers/crt/time.h | 44 ++++++++++++++++++++++++++++++++----
1 file changed, 39 insertions(+), 5 deletions(-)
diff --git a/mingw-w64-headers/crt/time.h b/mingw-w64-headers/crt/time.h
index d70a70717..d50d43f55 100644
--- a/mingw-w64-headers/crt/time.h
+++ b/mingw-w64-headers/crt/time.h
@@ -247,9 +247,11 @@ static __inline int __CRTDECL timespec_get(struct
timespec* _Ts, int _Base) { re
#endif
static __inline double __CRTDECL difftime(time_t _Time1,time_t _Time2) {
return _difftime32(_Time1,_Time2); }
static __inline struct tm *__CRTDECL localtime(const time_t *_Time) { return
_localtime32(_Time); }
-static __inline errno_t __CRTDECL localtime_s(struct tm *_Tm,const time_t
*_Time) { return _localtime32_s(_Tm,_Time); }
static __inline struct tm *__CRTDECL gmtime(const time_t *_Time) { return
_gmtime32(_Time); }
-static __inline errno_t __CRTDECL gmtime_s(struct tm *_Tm, const time_t
*_Time) { return _gmtime32_s(_Tm, _Time); }
+#if !__STDC_WANT_LIB_EXT1__ || defined(__cplusplus) /* Conflict with C11
variants */
+static __inline errno_t __CRTDECL localtime_s(struct tm *_Tm, const time_t
*_Time) { return _localtime32_s(_Tm,_Time); }
+static __inline errno_t __CRTDECL gmtime_s(struct tm *_Tm, const time_t
*_Time) { return _gmtime32_s(_Tm, _Time); }
+#endif
static __inline char *__CRTDECL ctime(const time_t *_Time) { return
_ctime32(_Time); }
static __inline errno_t __CRTDECL ctime_s(char *_Buf,size_t _SizeInBytes,const
time_t *_Time) { return _ctime32_s(_Buf,_SizeInBytes,_Time); }
static __inline time_t __CRTDECL mktime(struct tm *_Tm) { return
_mktime32(_Tm); }
@@ -261,9 +263,11 @@ static __inline int __CRTDECL timespec_get(struct
timespec* _Ts, int _Base) { re
#endif
static __inline double __CRTDECL difftime(time_t _Time1,time_t _Time2) {
return _difftime64(_Time1,_Time2); }
static __inline struct tm *__CRTDECL localtime(const time_t *_Time) { return
_localtime64(_Time); }
-static __inline errno_t __CRTDECL localtime_s(struct tm *_Tm,const time_t
*_Time) { return _localtime64_s(_Tm,_Time); }
static __inline struct tm *__CRTDECL gmtime(const time_t *_Time) { return
_gmtime64(_Time); }
+#if !__STDC_WANT_LIB_EXT1__ || defined(__cplusplus) /* Conflict with C11
variants */
+static __inline errno_t __CRTDECL localtime_s(struct tm *_Tm, const time_t
*_Time) { return _localtime64_s(_Tm,_Time); }
static __inline errno_t __CRTDECL gmtime_s(struct tm *_Tm, const time_t
*_Time) { return _gmtime64_s(_Tm, _Time); }
+#endif
static __inline char *__CRTDECL ctime(const time_t *_Time) { return
_ctime64(_Time); }
static __inline errno_t __CRTDECL ctime_s(char *_Buf,size_t _SizeInBytes,const
time_t *_Time) { return _ctime64_s(_Buf,_SizeInBytes,_Time); }
static __inline time_t __CRTDECL mktime(struct tm *_Tm) { return
_mktime64(_Tm); }
@@ -309,12 +313,21 @@ struct timezone {
#endif
#ifdef _POSIX_THREAD_SAFE_FUNCTIONS
+#ifdef _USE_32BIT_TIME_T
__forceinline struct tm *__CRTDECL localtime_r(const time_t *_Time, struct tm
*_Tm) {
- return localtime_s(_Tm, _Time) ? NULL : _Tm;
+ return _localtime32_s(_Tm, _Time) ? NULL : _Tm;
}
__forceinline struct tm *__CRTDECL gmtime_r(const time_t *_Time, struct tm
*_Tm) {
- return gmtime_s(_Tm, _Time) ? NULL : _Tm;
+ return _gmtime32_s(_Tm, _Time) ? NULL : _Tm;
}
+#else
+__forceinline struct tm *__CRTDECL localtime_r(const time_t *_Time, struct tm
*_Tm) {
+ return _localtime64_s(_Tm, _Time) ? NULL : _Tm;
+}
+__forceinline struct tm *__CRTDECL gmtime_r(const time_t *_Time, struct tm
*_Tm) {
+ return _gmtime64_s(_Tm, _Time) ? NULL : _Tm;
+}
+#endif
__forceinline char *__CRTDECL ctime_r(const time_t *_Time, char *_Str) {
return ctime_s(_Str, 0x7fffffff, _Time) ? NULL : _Str;
}
@@ -327,6 +340,27 @@ __forceinline char *__CRTDECL asctime_r(const struct tm
*_Tm, char * _Str) {
}
#endif
+#if __STDC_WANT_LIB_EXT1__
+#define __STDC_LIB_EXT1__ 1
+/* Optional C11 functions are incompatible with the MSVC variants.
+ Both variants are provided for C++. */
+#ifdef _USE_32BIT_TIME_T
+__forceinline struct tm *__CRTDECL localtime_s(const time_t *_Time, struct tm
*_Tm) {
+ return _localtime32_s(_Tm, _Time) ? NULL : _Tm;
+}
+__forceinline struct tm *__CRTDECL gmtime_s(const time_t *_Time, struct tm
*_Tm) {
+ return _gmtime32_s(_Tm, _Time) ? NULL : _Tm;
+}
+#else
+__forceinline struct tm *__CRTDECL localtime_s(const time_t *_Time, struct tm
*_Tm) {
+ return _localtime64_s(_Tm, _Time) ? NULL : _Tm;
+}
+__forceinline struct tm *__CRTDECL gmtime_s(const time_t *_Time, struct tm
*_Tm) {
+ return _gmtime64_s(_Tm, _Time) ? NULL : _Tm;
+}
+#endif
+#endif
+
/* POSIX 2008 says clock_gettime and timespec are defined in time.h header,
but other systems - like Linux, Solaris, etc - tend to declare such
recent extensions only if the following guards are met. */
--
2.39.0
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public