首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >修复c++中类型转换警告的最佳方法

修复c++中类型转换警告的最佳方法
EN

Stack Overflow用户
提问于 2017-10-17 14:46:03
回答 4查看 1.1K关注 0票数 3

所以,当我收到这样的警告时,我从来不知道该怎么做,所以我需要其他专业程序员的建议。当我收到这类警告(而不是错误)时

警告C4267:“=”:将“size_t”转换为“ULONG”,可能会丢失数据

(省略其他上下文代码)

代码语言:javascript
复制
wchar_t pszName[CREDUI_MAX_USERNAME_LENGTH + 1] = L"user";
wchar_t pszPwd[CREDUI_MAX_PASSWORD_LENGTH + 1] = L"password";

// ..

COAUTHIDENTITY authIdent;

// ...

memset(&authIdent, 0, sizeof(COAUTHIDENTITY));
authIdent.PasswordLength = wcslen(pszPwd);
authIdent.UserLength = wcslen(pszName);

问题显然是wcslen()返回一个size_t,而authIdent.PasswordLength是一个ULONG。处理这些警告的最好方法是什么?是否有一个winapi函数,他们希望我使用而不是wcslen()?

编辑:谢谢所有伟大的回应,大家!

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-10-17 15:52:55

字符串长度最自然的类型是size_t。实际上,字符串的大小将适合于ULONGsize_t。然而,这样的分配绝对值得一次警告。想象一下这个愚蠢的错误:

代码语言:javascript
复制
ULONG x = 0;
authIdent.PasswordLength = x - 1;

很容易声称这种错误从未发生过,但通过提供一个不太容易出错的接口(这也可以防止丑陋的memset出现在用户代码中),防止这类错误的发生也同样容易:

代码语言:javascript
复制
struct my_COAUTHIDENTITY {
    private:
        COAUTHIDENTITY authIdent;
    public: 
        my_COAUTHIDENTITY() {
            memset(&authIdent, 0, sizeof(COAUTHIDENTITY));
        }
        void setPasswd(wstring passwd) {
            ...
            authIdent.PasswordLength = static_cast<ULONG>(passwd.size());
        }
 };
票数 2
EN

Stack Overflow用户

发布于 2017-10-17 14:52:05

每个编译器警告都需要逐个案例处理。

您将在您的平台上收到此警告,因为ULONG是32位无签名,而std::size_t是64位无签名。

但考虑到(1)您的字符串不太可能比ULONG长,而且(2)两个无符号类型之间的转换总是定义良好的,我会做实际的事情并使用static_cast

代码语言:javascript
复制
static_cast<ULONG>(wcslen(pszPwd))
票数 5
EN

Stack Overflow用户

发布于 2017-10-17 14:53:19

由于您可以合理地相信长度将适合于ULONG,所以您可以安全地使用:

代码语言:javascript
复制
static_cast<ULONG>(wcslen(pszPwd))

否则你可以:

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46792956

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档