C++:localtime_s 在 GCC 中的位置

C++: location of localtime_s in GCC

遵循 documentation 并使用 gcc-11.2.0 编译

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

我无法在我的程序中使用 localtime_s

#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’?

我是不是做错了什么或者 localtime_s 在 GCC 中不可用?或者它只适用于纯C程序(例如,用gcc -std=c11编译)?

非常感谢您的帮助!

标准中以 _s 结尾的许多函数最初由 Microsoft 开发,作为以 _r 结尾的函数的替代函数。

在 Linux 系统上,localtime_s 未定义,但 localtime_r 已定义,并且具有相同的 parameters/return 类型,因此请改用它。

如其他地方所述,_s 函数最初由 Microsoft 开发。它们作为规范性但可选的附件 K 被纳入 C11。

遗憾的是,标准指定的内容与 Microsoft 实施的内容之间存在差异。

Microsoft 使用以下接口实现了 localtime_s()

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

标准 C11 要求 localtime_s():

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

而POSIX定义localtime_r():

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

如您所见,标准 C 和 Microsoft 函数 localtime_r() 具有非常不同的接口 — 参数的顺序相反并且 return 类型不同。相比之下,标准 C 和 POSIX 函数之间的区别只是名称。

这是 _s 函数的一个相当普遍的问题。 ISO 标准化的接口不同于 Microsoft 标准化的接口,通常有充分的理由。您可以在问答 Do you use the TR 24731 'safe' functions? 中找到有关 _s 函数问题的其他信息。它有许多关于标准 C 和 _s(安全)函数的 Microsoft 变体之间差异的其他示例的参考,以及表明安全函数并不是那么有用的讨论文档。