我对静态源代码分析一个大的项目,一切编译成功,除了一两件事。 我在标题中提供的错误信息。 这让我困惑的一点是,它提供了一个错误信息,说是不安全的。 我认为这应该只是警告,而不是错误。 顺便说一句,我使用的Visual Studio 2012这里是我的错误,在的ctime代码的一部分。 如果有人能帮助我克服这个错误,我会很高兴。
void CppCheckExecutor::reportProgress(const std::string &filename, const char stage[], const std::size_t value)
{
(void)filename;
if (!time1)
return;
// Report progress messages every 10 seconds
const std::time_t time2 = std::time(NULL);
if (time2 >= (time1 + 10)) {
time1 = time2;
// current time in the format "Www Mmm dd hh:mm:ss yyyy"
const std::string str(std::ctime(&time2));
// format a progress message
std::ostringstream ostr;
ostr << "progress: "
<< stage
<< ' ' << value << '%';
if (_settings->_verbose)
ostr << " time=" << str.substr(11, 8);
// Report progress message
reportOut(ostr.str());
}
}
如果你看一下的描述的ctime你会注意到:
这个函数返回一个指向静态数据 ,而不是线程安全的。 此外,它修改可能与gmtime的和localtime被共享的静态TM对象 。 POSIX标志着这一功能已经过时,建议改为strftime的。
该行为可能会未定义的time_t的时间超过25个字符(如一年10000)导致字符串中的值
......这是一个很大的事情操心。
在另一方面,如果你看的strftime :
为size_t的strftime(字符* STR,为size_t计数,为const char *格式,TM *时间);
返回值
写入到字符数组字节数指向STR不包括上成功终止“\ 0”。 如果达到计数可以存储整个字符串之前,则返回0和内容是不确定的。
所有参数都是明确的,让你完全控制可能的数据争,并没有提供溢出以及缓冲的风险。
这是C-方式虽然,C ++介绍<chrono>
其中特定功能std::put_time
也可以用来输出时间到一个流:
#include <iostream>
#include <iomanip>
#include <ctime>
#include <chrono>
int main() {
std::time_t const now_c = std::time();
std::cout << "One day ago, the time was "
<< std::put_time(std::localtime(&now_c), "%F %T") << '\n';
}
这甚至更好,因为你再也不用担心可能缓冲区溢出。
如果你确定你的代码中没有安全问题,则可以通过禁用此#pragma warning(disable : 4996)
。
是的,这应该只是警告,而不是错误。 为了得到一个简单的警告,而不是错误,禁用VS项目SDL检查(在配置属性 - > C / C ++ - >常规选项卡)。
std::ctime
是不是有两个原因线程安全的:
- 它可以修改类型的全局对象
std::tm
由多个功能共用。 - 它会修改全局
char
数组,并返回一个指针数组。
没有为冲突,如果您有调用其他线程潜在std::gmtime
, std::localtime
,或std::ctime
。
做的最好的事情就是该呼叫转换std::ctime
到调用std::strftime
。 这是与POSIX,它认为是一致ctime
过时,且建议的用法strftime
代替它。
2017年VS:
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <ctime>
#include <chrono>
int main() {
std::time_t const now_c = std::time(NULL);
auto s = std::put_time(std::localtime(&now_c), "%F %T");
std::cout << s << std::endl;
}
但是,您将收到呢:
.... CPP(31):警告C4996: '本地时间':此函数或变量可能是不安全的。 考虑使用localtime_s代替。 要禁用弃用,使用_CRT_SECURE_NO_WARNINGS。 详细信息请参见在线帮助。
防止你可以使用:
errno_t err;
struct tm time_info;
time_t time_create = time(NULL);
localtime_s(&time_info, &time_create);
char timebuf[26];
err = asctime_s(timebuf, 26, &time_info);
纯C从MSDN ...旧的方式部分地采取了..