函数参数

时间:2017-01-26 23:46:09

标签: c winapi visual-studio-2015 type-conversion windows-7-x64

我想知道显式转换传递给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 );

根据我的理解,两个函数调用都应该产生编译警告。为什么编译器似乎有偏差?

0 个答案:

没有答案