问题
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 aDWORD
.
To solve this error I did:
c-style
casting as(DWORD)(0U)
in functioncall(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