警告 C26411
パラメーター 'parameter' は一意のポインターへの参照であり、再割り当てやリセットは行われず、代わりに
T*
またはT&
を使用します (r.33)
関数への一意のポインターを参照渡しで渡す場合、そのリソースが関数内で解放または転送される可能性があります。 関数がパラメーターを使用してリソースにアクセスする場合は、生ポインターまたは参照を渡しても問題はありません。 詳細については、「 C++ Core Guidelines rule R.33: unique_ptr<widget>& パラメーターを使用して、関数がウィジェットを再封印することを表しますを参照してください。
解説
警告 C26410 からの制限もここで適用されます。
ユニーク ポインターへの
release
またはreset
アクセスを検出するヒューリスティックはナイーブです。 割り当て演算子とreset
という名前の関数の呼び出しのみを検出します (大文字と小文字は区別されません)。 明らかに、この検出では、スマート ポインターの変更の可能性があるすべてのケースがカバーされているというのではありません。 (例えば、std::swap
や、カスタム スマート ポインターの中のconst
以外の特殊な関数は検出しません)。 この警告により、カスタム型に対して多くの誤検知が生成される可能性があります。また、一部のシナリオでは標準の一意のポインターを処理します。 スマート ポインターに重点を置くチェックを実装し、ヒューリスティックを改善する必要があります。スマート ポインターが多くの場合、テンプレートであるという事実は、興味深い制限を引き出します。 使用されていない場合、コンパイラはテンプレート内のテンプレート コードを処理する必要はありません。 スマート ポインター インターフェイスを限定的に使用するコードでは、チェッカーによって予期しない結果が生じる可能性があります。 一部の関数が使用されない可能性があるため、チェッカーはテンプレート型のセマンティクスを適切に識別できません。 標準の
std::unique_ptr
の場合、この制限は型の名前を認識することで軽減されます。 この分析は、今後、よりよく知られているスマート ポインターに対応できるように拡張される可能性があります。暗黙的な参照によるキャプチャを行うラムダ式は、一意のポインターへの参照に関する驚くべき警告につながる可能性があります。 現時点では、ラムダでキャプチャされた参照パラメーターはすべて、リセットされるかどうかに関係なく報告されます。 今後のリリースでは、ラムダ フィールドとラムダ パラメーターを関連付けるヒューリスティックが拡張される可能性があります。
コード分析名: NO_REF_TO_UNIQUE_PTR
例: 不要な参照
void TraceValid(std::unique_ptr<Slot> &slot) // C26411
{
if (!IsDamaged(slot.get()))
std::cout << *slot.get();
}
void ReleaseValid(std::unique_ptr<Slot> &slot) // OK
{
if (!IsDamaged(slot.get()))
slot.reset(nullptr);
}