2017-08-18 227 views
2

我正在將代碼從32位vs2012遷移到64位vs2015。警告C4267'參數':從'size_t'轉換爲'DWORD',可能會丟失數據

我遇到了我的程序如下函數調用:

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

其聲明是在位於c:\Program Files (x86)\Windows Kits\8.0\Include\um\wincrypt.hwincrypt.h(貌似不被修改)。

的聲明是:

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

DWORD dwFlags中:這裏問題在於0u是unsigned int類型和功能需要DWORD

爲了解決這個錯誤我所做的:

  • c-style鑄塑(DWORD)(0U)在功能call(tried size_t, unsigned int)
  • static_cast
  • 嘗試創建一個新的變量和鑄造它

但警告仍然存在

看起來我必須改變函數調用

有人可以建議我如何解決這個問題。

請詢問是否需要更多細節。

Warning image details
later Warning image details

+0

你正在考慮'0u'是問題。對我來說,看起來問題應該圍繞第三個參數,其中size_t值用於提供雙字參數。 – Yunnosch

+1

問題不在於'0u'表達式,而是['std :: wcslen'](http://en.cppreference.com/w/cpp/string/wide/wcslen)和['sizeof '](http://en.cppreference.com/w/cpp/language/sizeof)運算符返回'size_t'。這可能是64位類型,而「DWORD」是32位類型。 –

回答

2

您所想0U是問題。
對我來說,它看起來像問題應該圍繞第三個參數,其中size_t值用於提供雙字參數。

正如SomeProgrammerDude所解釋的,size_t在新環境下可能是64位,而DWORD是32位。這解釋了新平臺的不匹配。

在32位平臺上,您沒有收到警告(我假設),可能是因爲size_t是32位,沒有丟失信息的風險。

您報告說,鑄造避免了警告,這表明0u不是問題。
警告似乎與0u一致的事實可能是由於編譯器抱怨整個函數調用並引腳指向它的結尾,即關閉),這與恰好在同一行上0u
將所有)移動到單獨行的實驗(結果顯示爲兩個屏幕截圖之間的差異)已經證實了這一點。

請注意,鑄造只能避免警告,這與解決問題不同。
(您明智地問鑄造的安全,我建議這樣做,在一個單獨的問題。)

0

我試圖鑄造第三arguement這解決了警告張貼由Yunnosch

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

我不知道爲什麼編譯器提出0u作爲問題

+0

是什麼讓你認爲編譯器對'0u'的投訴? – Yunnosch

+0

它提出了警告指向包含「0u」的行號 –

+0

這是不同於第三個參數的行嗎?奇怪。你能表演嗎? – Yunnosch

0

這個問題已經得到解答。但是,我想就如何減少審查和分析此類警告所需的工作提供更多建議。我建議使用PVS-Studio靜態代碼分析器來代替編譯器警告。它包含一組專門用於查找64位錯誤的診斷程序。首先,該組允許檢測比任何編譯器能夠檢測到更多的錯誤,其次,分析儀更加智能。讓我們來看一個例子:

如果分析儀不知道有關緩衝區的任何信息(理論上,字符串可能很大),分析儀將產生警告。舉例:

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

V107將函數'F'的第一個參數's'隱式轉換爲32位類型。 consoleapplication1.cpp 15

但是,當分析儀確定字符串很小並且整數變量存儲一個較小的值時,分析儀將保持沉默狀態並且不會產生不必要的警告。舉個例子:

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

的分析知道,AUTH_ENCRYPTION_KEY緩衝區無法容納一個字符串是超過99個字符。因此,'s'變量將具有一個可以保證適合DWORD類型變量的值。 PVS-Studio分析器不會產生警告,這反過來又節省了開發人員在將源代碼移植到64位平臺時的時間。

P.S.我向所有參與開發64位應用程序的人員推薦以下材料: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

相關問題