In C++11 you still have to use std::localtime
and std::gmtime
as indirection to print a std::chrono::time_point
. These functions are not safe to use in a multithreaded environment as introduced with C++11 because they return a pointer to an internal static struct. This is especially annoying since C++11 introduced the convenient function std::put_time
which is nearly unusable for the same reason.
Why is this so fundamental broken or do I overlook something?
APPLICATION USAGE. The gmtime_r() function is thread-safe and returns values in a user-supplied buffer instead of possibly using a static data area that may be overwritten by each call.
The function strftime() is MT-Safe as long as no thread calls setlocale() while this function is executing.
According to N2661, the paper that added <chrono>
:
This paper does not offer calendrical services except for a minimal mapping to and from C's
time_t
.As this paper does not propose a date/time library, nor specify epochs, it also does not address leap seconds. However, a date/time library will find this to be an excellent foundation on which to build.
This paper does not propose a general purpose physical quantities library.
This paper proposes a solid foundation that, in the future, could provide a compatible starting point for a general physical units library. While such a future library might take any of several forms, the present proposal stops well short of actually being a physical units library. This proposal is time-specific, and continues to be motivated by the time-related needs of the threading library.
The major goal of this proposal is to satisfy the needs of the standard library threading API in a manner which is easy to use, safe to use, efficient, and flexible enough to not be obsolete 10 or even 100 years from now. Every feature contained in this proposal is here for a specific reason with practical use cases as motivation. Things that fell into the category of "cool", or "that sounds like it might be useful", or "very useful but not needed by this interface" have not been included. Such items might appear in other proposals, and possibly target a TR.
Note that the major goal of <chrono>
is "to satisfy the needs of the standard library threading API", which does not require calendar services.
localtime
and gmtime
have internal storage that is static, which means they are not threadsafe (we have to return a pointer to a data structure, so it either has to be allocated dynamically, a static value or a global value - since allocating dynamically would leak memory, that is not a reasonable solution, meaning that it has to be a global or static variable [theoretically, one could allocate and store in TLS, and make it threadsafe that way]).
Most systems do have threadsafe alternatives, but they are not part of the standard library. For example, Linux/Posix has localtime_r
and gmtime_r
, which takes an extra parameter for the result. See for example http://pubs.opengroup.org/onlinepubs/7908799/xsh/gmtime.html
Similarly, Microsoft libraries have gmtime_s
, which is also re-entrant and works in a similar way (passing in the output parameter as an input). See http://msdn.microsoft.com/en-us/library/3stkd9be.aspx
As to why the standard C++11 library doesn't use these functions? That you'd have to ask the people who wrote that specification - I expect it's portability and convenience, but I'm not entirely sure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With