質問

だから私は、マイクロソフトのソース注釈言語(VS 2012-2013のフレーバー)を使用して、ポインタとの関数契約を記述することに合理的に準拠しています。

私が興味があるのは、私が注釈付きのCalleeが最初にポインタをチェックしていない場合よりも_In_ _Pre_defensive_と別の結果を得ることを期待していることです。 [当社の従来の関数の多くはこれらのパラメータの有効な入力を期待していますが、ポリシーはダブルチェックすることです。]防御していない守備されていない関数を説明するための静的分析エラーがありますか?

docs 、< / P>

信頼境界に関数が表示されている場合は、_pre_defaind_アノテーションを使用することをお勧めします。 「防御的な」修飾子は、呼び出し時点でインタフェースを厳密にチェックする必要があることを示すために特定の注釈を変更しますが、実装本体では、誤ったパラメータが渡される可能性があると仮定する必要があります。その場合、 _PRE_DEFASS_が信頼境界では、呼び出し側がNULLを渡しようとするとエラーが発生しますが、その関数本文は、パラメータがNULLになる可能性があるかのように分析されます。最初にNULLの場合は最初にチェックすることなくポインタを参照しようとする試みはフラグが立てられます。

コード分析のための小さなデモプログラムです。私の関数の4つすべては静的分析でC6387を示していますが、私の「防御的」関数が実際にfun0()のように入力をチェックしていないという追加の表示を見ていました。この修飾子を追加することに対する利点はありますか?それは本当に宣言を巡回しているので、それが助けていないのであれば、そこに置くことを正当化するのは難しいです。

// SAL2013.cpp : Defines the entry point for the console application.

#include "stdafx.h"

// pre-defensive annotation, but no check
void fun0(_In_ _Pre_defensive_ int* pInt)
{
    auto oops = *pInt;
}

// not defensive, no check
void fun1(_In_ int* pInt)
{
    auto oops = *pInt;
}

// defensive check, but not annotated defensively
void fun2(_In_ int* pInt)
{
    if (pInt != nullptr)
    {
        auto oops = *pInt;
    }
}

// defensive, with annotation
void fun3(_In_ _Pre_defensive_ int* pInt)
{
    if (pInt != nullptr)
    {
        auto oops = *pInt;
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    int* p = nullptr;
    fun0(p); // C6387 Invalid Parameter Value
    fun1(p); // C6387 Invalid Parameter Value
    fun2(p); // C6387 Invalid Parameter Value
    fun3(p); // C6387 Invalid Parameter Value

    return 0;
}
.

ボーナス質問:私はsal.hで見ています。_In_defensive_(annotes)注釈がありますが、それを使う方法がわかりません。

ありがとう。

役に立ちましたか?

解決

AFAICT _defensive_注釈を追加するときに、現在(公開)の違いはありません。ただし、マイクロソフトには内部的に使用する追加のアナライザーがあります。これらは注釈を利用するかもしれず、また将来一般の人々にリリースされるかもしれません。

それはトレードオフです。宣言を乱雑に思っていると思われる場合は、それらを削除するのに本当の害はありません。一方、将来的にはこれが使用される可能性があり、それはまた意図された使用に関する文書として使用することができます。

編集:_Use_decl_annotations_として、_In_defensive_(annotes)注釈をすべての注釈に適用できます(_Pre_defensive_で指定されています)。また、これにより注釈を別の場所に配置することができます。

_In_defensive(_Pre_satisfies_(pInt != nullptr))
void fun3(int* pInt)
{
}
.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top