警告 C26429
シンボルは null 値のテストを行うことはなく、次のように
gsl::not_null
マークできます。
C++ コア ガイドライン: F.23: "null" が有効な値ではないことを示すために a not_null<T>
を使用する
アサートを使用して、ポインター値の有効性に関する前提条件を適用するのが一般的な方法です。 問題は、アサートがインターフェイス (戻り値の型やパラメーターなど) を介して仮定を公開してはいけないという問題です。 アサートは維持が難しく、他のコード変更と常に同期することも困難です。 ガイドライン サポート ライブラリから、 gsl::not_null
null 値を指定してはいけないリソースをマークすることをお勧めします。 このルールUSE_NOTNULL
は、null のチェックを省略する場所を特定するのに役立ちます。そのため、使用するようにgsl::not_null
更新できます。
解説
ルールのロジックでは、null チェック (または null 以外の値の適用) が正当化されるように、ポインター変数を逆参照するコードが必要です。 そのため、警告は、ポインターが逆参照され、null のテストが行われなかった場合にのみ生成されます。
現在の実装では、プレーン ポインター (またはそのエイリアス) のみが処理され、スマート ポインターにも適用できますが、 gsl::not_null
スマート ポインターは検出されません。
変数は、次のコンテキストで使用される場合、null に対してチェックとしてマークされます。
- たとえば、
if (p) { ... }
分岐条件のシンボル式として; - ビットごとではない論理演算
- 1 つのオペランドが 0 に評価される定数式である比較演算
ルールには完全なデータフロー追跡がありません。 間接チェックが使用される場合 (中間変数が null 値を保持し、後で比較で使用される場合など) に、不適切な結果が生じる可能性があります。
コード分析名: USE_NOTNULL
例
隠された期待:
using client_collection = gsl::span<client*>;
// ...
void keep_alive(const connection *connection) // C26429
{
const client_collection clients = connection->get_clients();
for (ptrdiff_t i = 0; i < clients.size(); i++)
{
auto client = clients[i]; // C26429
client->send_heartbeat();
// ...
}
}
隠された期待が明らかに gsl::not_null
:
using client_collection = gsl::span<gsl::not_null<client*>>;
// ...
void keep_alive(gsl::not_null<const connection*> connection)
{
const client_collection clients = connection->get_clients();
for (ptrdiff_t i = 0; i < clients.size(); i++)
{
auto client = clients[i];
client->send_heartbeat();
// ...
}
}