傳回未初始化的記憶體 'parameter-name'。
備註
透過函式的成功路徑不會設定 _Out_ 批注參數。
此警告的目的是避免由函式的呼叫端使用未初始化的值。 分析器假設呼叫端不會在函式呼叫之前初始化任何批注 _Out_ 的參數,並檢查函式是否初始化它們。 如果函式傳回值,表示它發生錯誤或未成功,分析器不會發出這個警告。 若要修正此問題,請務必在所有成功的傳回路徑下初始化 _Out_ 參數。 錯誤訊息包含未初始化 參數的範例路徑行號。
如果初始化行為是設計方式,則不正確或遺漏 SAL 註釋可能是警告的原因。 您通常可以使用下列兩種方式之一來解決這些案例:變更 _Out_ 為更適當的註釋,或使用 _Success_() 註釋來協助定義函式的成功/錯誤狀態。 靜態分析工具在分析函式的呼叫位置時,請務必在函式上具有正確的註釋。
修正參數批註的變更
如果參數應該已經處於初始化狀態,且函式有條件地修改它,則 _Inout_ 批注可能更合適。 如果沒有其他高階批註符合預期的行為,您可以使用低階註釋,例如 _Pre_null_、 _Pre_satisfies_()和 _Post_satisfies_() ,以提供對參數預期狀態的額外彈性和控制。 如需參數批註的詳細資訊,請參閱 標註函式參數和傳回值。
藉由定義成功的傳回路徑來修正
當程式代碼未在函式的成功路徑中初始化 _Out_ 參數時,分析器只會發出這個警告。
_Success_如果沒有註釋,也沒有函式傳回類型批註,則會考慮所有傳回路徑都成功。 如需和類似註釋的詳細資訊 _Success_ ,請參閱 成功/失敗批註。
程式碼分析名稱:RETURN_UNINIT_VAR
範例
下列程式代碼會產生此警告。 因為函式會傳 void回 ,因此分析器會將所有路徑視為成功。 在此情況下,正確的修正可能是調整 語句的 if 邏輯,但在真實世界的程序代碼中,它通常不是那麼簡單,解決方案取決於函式的預期行為。
#include <sal.h>
void AlwaysInit(_Out_ int* output, int input) // : warning C6101: Returning uninitialized memory '*p'.: Lines: 2, 4, 9, 14, 2
{
if( input > 0 )
{
*output = input;
return;
}
else if( input < 0 )
{
*output = 0;
return;
}
return; // Oops, input was 0
}
為了讓解決方案更有趣,我們假設當 是 output時input初始化0並無效。 其中一種方法是將函式傳回值修改為不同類型的 ,例如 bool。 然後,新增 _Success_ 批注以定義成功的傳回路徑。
_Success_(return == true)
bool InitNotZero(_Out_ int* output, int input)
{
if( input > 0 )
{
*output = input;
return true;
}
else if( input < 0 )
{
*output = 0;
return true;
}
return false;
}
如果此模式在程式代碼基底中很常見,您可以將批註新增至傳回類型。 Windows SDK 中的 HRESULT 之類的錯誤碼會提供註釋的行為 _Success_ ,而不需要將它新增至每個函式。 如果您已經使用批注型別做為傳回型別,而且想要覆寫行為,請將批註新增至函式,如上一個範例所示。
using SuccessWhenTrue = _Success_(return == true) bool;
SuccessWhenTrue InitNotZero(_Out_ int* output, int input)
{
// ...
}