Home > Software engineering >  C : location of localtime_s in GCC
C : location of localtime_s in GCC

Time:11-17

Following the documentation and compiling with gcc-11.2.0 like so

g   -std=c  17 -pthread -O3 -flto -fPIC ...

I am not able to use localtime_s in my program:

#define __STDC_WANT_LIB_EXT1__ 1
#include <time.h>

using SystemClock = std::chrono::system_clock;
const auto in_time_t = SystemClock::to_time_t(SystemClock::now());

struct tm buf; localtime_s(&in_time_t, &buf);
// error: there are no arguments to ‘localtime_s’ that depend on a template parameter, 
//        so a declaration of ‘localtime_s’ must be available [-fpermissive]

struct tm buf; std::localtime_s(&in_time_t, &buf);
// error: ‘localtime_s’ is not a member of ‘std’; did you mean ‘localtime’?

Am I doing something wrong or localtime_s is not available in GCC? Or it is only available for pure C programs (for example, compiled with gcc -std=c11)?

Thank you very much for your help!

CodePudding user response:

As noted elsewhere, the _s functions were originally developed by Microsoft. They are incorporated into C11 as normative but optional Annex K.

Unfortunately, there are differences between what the standard specifies and what Microsoft implemented.

Microsoft implemented localtime_s() with the interface:

errno_t localtime_s(
   struct tm* const tmDest,
   time_t const* const sourceTime
);

Standard C11 requires localtime_s():

#define __STDC_WANT_LIB_EXT1__ 1
#include <time.h>
struct tm *localtime_s(const time_t * restrict timer,
       struct tm * restrict result);

And POSIX defines localtime_r():

struct tm *localtime_r(const time_t *restrict timer,
       struct tm *restrict result);

As you can see, the standard C and the Microsoft functions localtime_r() have very different interfaces — the arguments are in the reverse order and the return type is different. By contrast, the difference between the Standard C and POSIX functions is just the name.

This is a fairly general problem with the _s functions. The interface standardized by ISO differs from the interface standardized by Microsoft, often for good reasons. You can find other information about the problems with _s functions in the Q&A Do you use the TR 24731 'safe' functions?. It has numerous references to other examples of differences between the Standard C and Microsoft variations of the _s (safe) functions, and also to a discussion document suggesting that the safe functions are not all that helpful.

CodePudding user response:

Many of the functions specified in the standard ending with _s were originally developed by Microsoft as alternates to functions ending in _r.

On Linux systems, localtime_s is not defined but localtime_r is, and has the same parameters/return type, so use that instead.

  • Related