Warning C4267 'argument': conversion from 'size_t' to 'DWORD', possible loss of data

徘徊边缘 提交于 2019-12-12 19:09:16

问题


I am migrating code from 32bit vs2012 to 64bit vs2015.

I encountered the following function call in my program:

CryptHashData(hHash, 
                (BYTE*)AUTH_ENCRYPTION_KEY, 
                   wcslen(AUTH_ENCRYPTION_KEY) * sizeof(wchar_t), 
                   0u))

whose declaration is in wincrypt.h located in c:\Program Files (x86)\Windows Kits\8.0\Include\um\wincrypt.h (looks like not to be edited).

The declaration is:

WINADVAPI
BOOL
WINAPI
CryptHashData(
_In_                    HCRYPTHASH  hHash,
_In_reads_bytes_(dwDataLen)  CONST BYTE  *pbData,
_In_                    DWORD   dwDataLen,
_In_                    DWORD   dwFlags
);

DWORD dwFlags: Problem here is 0u is unsigned int and the function needs a DWORD.

To solve this error I did:

  • c-style casting as (DWORD)(0U) in function call(tried size_t, unsigned int)
  • static_cast
  • tried creating a new variable and casted it

But the warning still persists

Looks like I have to change in function call

Can someone suggest me how to solve this issue.

Please ask if more details are required.

Warning image details
later Warning image details


回答1:


You are thinking of the 0u being the problem.
For me it looks like the problem should be around the third parameter, where a size_t value is used to feed a dword parameter.

As SomeProgrammerDude has explained, size_t probably is 64bit in the new environment, while DWORD is 32bit. That explains the mismatch on the new platform.

On the 32bit platform you did not get a warning (I assume), probably because size_t was 32bit there, without risk of loosing information.

You reported that casting avoids the warning, this indicates that the 0u is not the problem.
The fact that the warning seems to be on the line with the 0u is probably caused by the compiler complaining about the whole function call and pin pointing the end of it, i.e. the closing ), which happens to be on the same line as the 0u.
The experiment of moving all ) to separate lines (result visible as the difference bwetween the two screenshots) has confirmed this.

Note that casting only avoided the warning, which is not the same as solving the problem.
(You wisely asked about the safety of casting, I recommend to do that in a separate question.)




回答2:


i tried casting the third arguement which solved the warning as posted by Yunnosch

(DWord)(wcslen(AUTH_ENCRYPTION_KEY) * sizeof(wchar_t))

i wonder why the compiler raised for 0u as the problem




回答3:


The question was already answered. However, I want to give an additional advice about how to reduce the effort required for reviewing and analyzing this kind of warnings. I suggest using the PVS-Studio static code analyzer instead of compiler warnings. It contains a specialized set of diagnostics for finding 64-bit errors. This set is, firstly, allows to detect more errors than any compiler can detect, and, secondly, the analyzer is more smart. Let's review an example:

If the analyzer does not know anything about the buffer (in theory, the string could be veeery large), the analyzer will produce a warning. An example:

void F(DWORD);
void A(const wchar_t *AUTH_ENCRYPTION_KEY)
{
  size_t s = wcslen(AUTH_ENCRYPTION_KEY) * sizeof(wchar_t);
  F(s);
}

V107 Implicit type conversion first argument 's' of function 'F' to 32-bit type. consoleapplication1.cpp 15

However, when the analyzer is sure that the string is small and the integer variable stores a small value, the analyzer will remain silent and will not produce an unnecessary warning. An example:

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);
}

The analyzer knows that the AUTH_ENCRYPTION_KEY buffer could not hold a string that is longer than 99 characters. Therefore, the 's' variable will have a value that is assured to fit into the DWORD type variable. And the PVS-Studio analyzer will not produce a warning, which, in turn, saves the developer's time when porting source code to 64-bit platform.

P.S. I recommend the following materials to everyone who is engaged in developing of 64-bit applications: 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.



来源:https://stackoverflow.com/questions/45750207/warning-c4267-argument-conversion-from-size-t-to-dword-possible-loss-of

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!