警告C4267'参数':从'size_t'转换为'DWORD',可能会丢失数据

时间:2017-08-18 06:49:13

标签: c++ visual-studio-2015 migration 32bit-64bit

我正在将代码从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
  • 尝试创建一个新变量并将其转换为

但警告仍然存在

看起来我必须更改函数调用

有人可以建议我如何解决这个问题。

请询问是否需要更多详细信息。

Warning image details
  later Warning image details

3 个答案:

答案 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++ applicationsA Collection of Examples of 64-bit Errors in Real ProgramsUndefined behavior is closer than you think