I was looking into the routines of the C time library, since I needed a way to keep track of time on the log file of a program. I found the way to do it was to have a
asctime(strcut tm* argument)
"The function also accesses and modifies a shared internal object,
which may introduce data races on concurrent calls to gmtime and
localtime. Some libraries provide an alternative function that avoids
this data race: localtime_r (non-portable)."
struct tm MyProgramStruct; localtime(&Rawtime, &MyProgramStruct);
/* localtime example */
#include <stdio.h> /* puts, printf */
#include <time.h> /* time_t, struct tm, time, localtime */
int main ()
struct tm * timeinfo;
timeinfo = localtime (&rawtime);
printf ("Current local time and date: %s", asctime(timeinfo));
So, who creates the struct tm object? Is it the C time library in the first time it is loaded?
According to the docs for the
localtime() function, it returns a pointer to a statically allocated struct. That struct belongs to the C library; the function provides a pointer to it. The fine details of exactly where it lives and exactly when and how storage for it is allocated don't matter and may vary from implementation to implementation. You just have to understand that different calls by the same process work with and provide pointers to the same struct.
That would mean that the first process that loads the library would declare the object and all other processes would just share this library with the object already declared?
No. You do not need to worry about the struct being shared between processes, only about it being shared across multiple calls and between multiple threads in the same process.
Wouldn't it be better, in order to avoid those Data Races issues, to just create a new struct tm object for each call and return a pointer to it so each program has its own structure? Maybe having a
struct tm MyProgramStruct; localtime(&Rawtime, &MyProgramStruct);instead of a single struct for every program using Ctime? Any reason it's done this way instead?
Again, it's not a cross-process problem, only an intra-process problem, which is still bad enough. Yes, that problem would be addressed by not sharing the struct, and that's what distinguishes the function
localtime_r(), where it is available. But the existing function cannot be changed to do the same, because that would introduce a new requirement on users to free the provided struct.
The designers of
localtime() wanted to make it easy to use, and indeed it is, as long as you don't run afoul of the shared data issue. If your program is single-threaded, then you can avoid it fairly easily.
localtime() is not the only standard library function with an issue of this sort.
Finally, is using C time library
localtimeroutine a bad practice because of the possibility of the unsynchronization of programs leading to a wrong output?
Not for that reason, no, because there is no cross-process problem. You do need to pay attention when using
localtime() and other functions with similar static storage, such as
strtok(). But you can judge on a program by program basis whether there is any data race -- you do not need to worry about interference from unspecified other programs.