localtime vs localtime_s 和适当的输入参数
Posted
技术标签:
【中文标题】localtime vs localtime_s 和适当的输入参数【英文标题】:localtime vs localtime_s and appropriate input arguments 【发布时间】:2013-01-01 10:55:15 【问题描述】:time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
这将返回:警告 C4996:“本地时间”:此函数或变量可能不安全。考虑改用 localtime_s。
time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime_s ( &rawtime );
当我将 localtime 更改为 localtime_s 时,我得到:错误 C2660: 'localtime_s' : function does not take 1 arguments
这是我认为第一块代码中发生的事情:
创建一个空的 time_t 变量。 创建指向在 ctime 中定义的 timeinfo 的指针 将 rawtime 写入 rawtime 引用将原始时间转换为对行人有意义的东西
-
我说的对吗?
localtime_s 需要什么第二个输入参数?
如果我忽略整个本地时间安全问题,可能会发生什么最糟糕的情况。
【问题讨论】:
是的,我立即找到了这个:msdn.microsoft.com/en-us/library/a442x3ye(v=vs.80).aspx 但我还不明白如何解释这些模板/泛型?方法的描述。就像我不理解一般形式的 wiki 数学文章的语法/符号一样。 struct tm* _tm 和 const time_t *time 就我真正告诉方法的内容而言对我没有任何意义......尽管我希望它这样做。 是的,我也有一些。 【参考方案1】:localtime
返回一个指向静态分配的struct tm
的指针。
使用 localtime_s,您传入一个指向 struct tm 的指针,localtime_s
将其结果数据写入其中,因此您的代码将从:
struct tm *timeinfo;
timeinfo = localtime(&rawtime);
类似于:
struct tm timeinfo;
localtime_s(&timeinfo, &rawtime);
这样,它会写入您的缓冲区,而不是拥有自己的缓冲区。
【讨论】:
通过这些更改,我得到了以下错误:错误 C2679:二进制“=”:未找到采用“errno_t”类型右手操作数的运算符(或没有可接受的转换)1> c :\Program Files\Microsoft Visual Studio 10.0\VC\include\wchar.h(1120): 可能是 'tm &tm::operator =(const tm &)' 1> 同时尝试匹配参数列表 '(tm, errno_t )' 错误 C2664: 'strftime' : 无法将参数 4 从 'tm' 转换为 'const tm *' 1> 没有可以执行此转换的用户定义转换运算符,或者无法调用该运算符 @ProGirlXOXO:这显然发生在你上面没有显示的代码中,但这可能是因为timeinfo
现在是一个struct tm
而不是一个指针,所以在其他函数使用它的地方,你'需要将timeinfo
更改为&timeinfo
。
这一行: &timeinfo = localtime_s ( &timeinfo, &rawtime );给出此错误:错误 C2440: '=' : cannot convert from 'errno_t' to 'tm *'
@ProGirlXOXO:重读答案。 localtime
返回一个指向 struct tm
的指针 -- localtime_s
not (它返回一个错误号来告诉您请求的转换是否成功)。【参考方案2】:
localtime_s 只是本地时间函数的微软实现,您可以安全地继续使用locatime
,因为它符合 C++ ISO 标准并且只有微软将其标记为“已弃用”。 localtime 函数本身在 C++ 世界中根本不被弃用。
localtime_s
reference 表示应该将这些参数传递给它:
_tm
Pointer to the time structure to be filled in.
time
Pointer to the stored time.
【讨论】:
FWIW,POSIX 标准更正函数是localtime_r
。工作原理完全相同,只是两个参数的顺序颠倒了。
localtime_s
是自 C11 以来standard 的一部分。
@Pietro 仅作为optional Annex K 的一部分,它事实上仅由Microsoft(较差地)实现。每Field Experience With Annex K — Bounds Checking Interfaces:“由于与规范有大量偏差,微软的实现不能被认为是符合或可移植的。”
@AndrewHenle - 感谢您指出这一点。只需阅读 cppreference:“Microsoft CRT 中 localtime_s 的实现与 C 标准不兼容,因为它颠倒了参数顺序。”【参考方案3】:
正如Lightness Races in Orbit 所指出的,localtime
和其他几个时间函数一样不是线程安全的。我想了解更多有关该主题的信息,我找到了a relevant blog post,并对此进行了粗略的解释。
下面的引用解释了为什么localtime
不是线程安全的:
[...] localtime 返回指向静态缓冲区 (std::tm*) 的指针。另一个线程可以调用该函数,并且可以在第一个线程完成读取 struct std::tm* 的内容之前覆盖静态缓冲区。
【讨论】:
以上是关于localtime vs localtime_s 和适当的输入参数的主要内容,如果未能解决你的问题,请参考以下文章
C语言编程函数localtime_s在VS 2020中写的程序参数错误,参数怎么写?
Windows 上 localtime_s() 多线程性能不佳的解决方法
C语言关于localtime_s()和asctime_s()两个函数的用法。
当我使用模板时,未在此范围GCC Linux环境中声明strerror_s,strcpy_s,localtime_s,sprintf_s?