警告 C6101

傳回未初始化的記憶體 '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
}

為了讓解決方案更有趣,我們假設當 是 outputinput初始化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)
{
  // ...
}

另請參閱

C++程式代碼的規則集
使用 SAL 註釋減少 C/C++ 程式碼的缺失