C++ 全局静态常量变量何时初始化?
我试图在网站上搜索这个问题,但没有找到确切的答案,尽管这个问题正在被讨论很多 我在cpp文件中有此声明,不在任何函数中:C++ 全局静态常量变量何时初始化?,c++,static,constants,global-variables,static-analysis,C++,Static,Constants,Global Variables,Static Analysis,我试图在网站上搜索这个问题,但没有找到确切的答案,尽管这个问题正在被讨论很多 我在cpp文件中有此声明,不在任何函数中: static const char* gText = "xxxxxxxxxxx"; 虽然它的大小是固定的,但当我试图将它复制到另一个char*变量时,我从静态分析工具(Klocwork)得到一个警告-关于可能的越界违规: char xText[32]; SecureZeroMemory(xText, 32); memcpy(xText, gText, strlen(gTex
static const char* gText = "xxxxxxxxxxx";
虽然它的大小是固定的,但当我试图将它复制到另一个char*变量时,我从静态分析工具(Klocwork)得到一个警告-关于可能的越界违规:
char xText[32];
SecureZeroMemory(xText, 32);
memcpy(xText, gText, strlen(gText));
是误报还是全局变量稍后初始化
谢谢 这是假阳性
strlen
可能被抽象为返回一个未知的正数,因此在分析模式时memcpy(dest,src,strlen(src))
只要src
是格式正确的字符串,分析器就不会意识到副本的读取部分是安全的
如果您使用的是strcpystrcpy
,那么分析器可能会得出这样的结论:在这种情况下没有问题。你有理由不这么做吗?函数strcpy
被认为是“不安全的”,但您的memcpy(..,src,strlen(src))
也非常不安全
编辑:此外,sellibitze在评论中提出了一个非常好的观点:原始代码中的
const
属性只适用于gText
所指的字符,而不适用于gText
本身。我认为这不是一个误判。有一个潜在的风险是,有人可能会出现并更改gText的长度,而没有意识到它不能超过32个字符。我肯定会在memcpy之前进行某种检查,以确保不会出现缓冲区溢出
e、 g
另外,我会用一个常量替换魔法数字32。这正是KLOCWORKS所指的行?它看起来是一个假阳性。顺便说一句,指针本身不是常量,因此,它可以更改为指向另一个更长的指针string@Sellibitze,你说得对。也许这就是KW抱怨它的原因。非常感谢。我对一条非常类似的评论发表了评论,其作者删除了答案。因此,我不再重复同样的事情,但是既然您已经决定使用
gText
的所有可能值,为什么要假设gText
是格式良好的字符串(在非格式良好的字符串的字符数组上调用strlen
)和MIN(..,32)中的32
应该是31
,如果xText
应该在副本后包含格式正确的字符串。@Pascal:使用memcpy而不是字符串函数对我来说意味着,其目的是获取一些将被视为固定大小字节块而不是C字符串的内容。这就是为什么我将限制设置为32。如果我试图复制一个字符串,我会使用StrncPy(或等效)来做它,或者这是C++ STD::String。谢谢。但是,作为BKM规则,不要进行部分复制。从未。它可能会导致奇怪的结果,很难找到根本原因。返回错误代码\改为引发异常。@IUnknownPointer:JeremyP规则:始终坚持严格的规则无法成功完成编程。你需要运用智慧。它们不是规则,更像是指导方针。在这种情况下,没有关于你意图的线索。也许你有理由只想把字符串的前32个字符放在某些网络协议的头中。谢谢。strcpy不能解决这个问题,但我将复制条件设置为只有长度不大于边界时才进行。谢谢
char xText[32];
SecureZeroMemory(xText, 32);
size_t lenToCopy = MIN(strlen(gText), 32);
memcpy(xText, gText, lenToCopy);