我想知道显式转换传递给RegSetValueW函数的cbData参数的值的正确方法是什么。 wcslen函数和sizeof运算符返回size_t,它似乎在Windows 64位上有8个字节。
WINADVAPI
LSTATUS
APIENTRY
RegSetKeyValueW (
_In_ HKEY hKey,
_In_opt_ LPCWSTR lpSubKey,
_In_opt_ LPCWSTR lpValueName,
_In_ DWORD dwType,
_In_reads_bytes_opt_(cbData) LPCVOID lpData,
_In_ DWORD cbData
);
PCWSTR pwszRegistryData = L"Stuff";
RegSetKeyValueW( HKEY_CURRENT_USER, L"RegistrySubKey",
L"RegistryValue", REG_SZ, pwszRegistryData,
(wcslen( pwszRegistryData ) + 1) * sizeof( WCHAR ) );
方法1 - 明确地将它们转换为两者(看起来有点过于谨慎):
(DWORD)(wcslen( pwszRegistryData ) + 1) * (DWORD)sizeof( WCHAR )
方法2 - 只显式转换结果:
(DWORD)((wcslen( pwszRegistryData ) + 1) * sizeof( WCHAR ))
方法3 - 依靠隐式转换来完成其工作:
(wcslen( pwszRegistryData ) + 1) * sizeof( WCHAR )
真实世界的结果:
编译器优化告诉我加息,因为二进制代码中的结果是数字常量。
修改
如果pwszRegistryData的长度非常长或将在运行时确定,那么RbMm提到的方法似乎还有很长的路要走。谢谢你的建议。
我还有一个问题;以下对RegSetKeyValueW的调用不会产生编译警告:
// On x64 platform: typedef unsigned long long size_t;
RegSetKeyValueW( HKEY_CURRENT_USER, L"RegistrySubKey",
L"RegistryValue", REG_SZ, pwszRegistryData,
(DWORD)(wcslen( pwszRegistryData ) + 1) * sizeof( WCHAR ) );
虽然以下示例确实产生了“可能的数据丢失”警告:
void func( unsigned long durrr ){}
unsigned long long herp = 5, derp = 2;
func( (unsigned long)(herp + 1) * derp );
根据我的理解,两个函数调用都应该产生编译警告。为什么编译器似乎有偏差?