我正在将代码从32位vs2012迁移到64位vs2015。
我在程序中遇到了以下函数调用:
CryptHashData(hHash,
(BYTE*)AUTH_ENCRYPTION_KEY,
wcslen(AUTH_ENCRYPTION_KEY) * sizeof(wchar_t),
0u))
其声明位于wincrypt.h
c:\Program Files (x86)\Windows Kits\8.0\Include\um\wincrypt.h
中(看起来不会被编辑)。
声明是:
WINADVAPI
BOOL
WINAPI
CryptHashData(
_In_ HCRYPTHASH hHash,
_In_reads_bytes_(dwDataLen) CONST BYTE *pbData,
_In_ DWORD dwDataLen,
_In_ DWORD dwFlags
);
DWORD dwFlags:问题是
0u
是unsigned int,函数需要DWORD
。
为了解决这个错误我做了:
c-style
在(DWORD)(0U)
call(tried size_t, unsigned int)
static_cast
但警告仍然存在
看起来我必须更改函数调用
有人可以建议我如何解决这个问题。
请询问是否需要更多详细信息。
答案 0 :(得分:2)
您正在考虑0u是问题 对我来说,问题应该是围绕第三个参数,其中size_t值用于提供dword参数。
正如SomeProgrammerDude所解释的那样,在新环境中size_t可能是64位,而DWORD是32位。这解释了新平台的不匹配。
在32位平台上你没有得到警告(我猜),可能是因为size_t是32位,没有丢失信息的风险。
您报告说施法避免了警告,这表示0u
不是问题
警告似乎与0u
一致的事实可能是因为编译器抱怨整个函数调用并指向它的结尾,即结束)
,这恰好发生在与0u
在同一行。
将所有)
移动到单独的行(结果显示为两个屏幕截图之间的差异)的实验证实了这一点。
请注意,施放仅避免了警告,这与解决问题不同 (你明智地询问了铸造的安全性,我建议在一个单独的问题中这样做。)
答案 1 :(得分:0)
我试图施放第三个争论,解决了Yunnosch发布的警告
(DWord)(wcslen(AUTH_ENCRYPTION_KEY) * sizeof(wchar_t))
我想知道为什么编译器提出0u作为问题
答案 2 :(得分:0)
这个问题已经回答了。但是,我想就如何减少审查和分析此类警告所需的工作量提供额外的建议。我建议使用PVS-Studio静态代码分析器而不是编译器警告。它包含一组用于查找64位错误的专用诊断程序。首先,该集合允许检测比任何编译器都能检测到的更多错误,其次,分析器更智能。我们来看一个例子:
如果分析仪对缓冲区一无所知(理论上,字符串可能很大),分析仪将发出警告。一个例子:
void F(DWORD);
void A(const wchar_t *AUTH_ENCRYPTION_KEY)
{
size_t s = wcslen(AUTH_ENCRYPTION_KEY) * sizeof(wchar_t);
F(s);
}
V107隐式类型将函数“F”的第一个参数's'转换为32位类型。 consoleapplication1.cpp 15
但是,当分析仪确定字符串很小且整数变量存储的值很小时,分析仪将保持静音并且不会产生不必要的警告。一个例子:
void F(DWORD);
void B(const wchar_t *src)
{
wchar_t AUTH_ENCRYPTION_KEY[100];
wcscpy_s(AUTH_ENCRYPTION_KEY, src);
size_t s = wcslen(AUTH_ENCRYPTION_KEY) * sizeof(wchar_t);
F(s);
}
分析器知道AUTH_ENCRYPTION_KEY缓冲区无法保存长度超过99个字符的字符串。因此,'s'变量将具有确保适合DWORD类型变量的值。并且PVS-Studio分析器不会产生警告,这反过来节省了开发人员将源代码移植到64位平台的时间。
P.S。我向所有参与开发64位应用程序的人推荐以下材料:Development of 64-bit C/C++ applications,A Collection of Examples of 64-bit Errors in Real Programs,Undefined behavior is closer than you think。