문제

따라서 저는 Microsoft Source Annotation Language(VS 2012-2013 버전)를 사용하여 포인터로 함수 계약을 설명하는 데 능숙합니다.

그런데 궁금한 점 중 하나는 다른 결과가 나올 것으로 예상했다는 것입니다. _In_ _Pre_defensive_ 주석이 달린 피호출자가 포인터를 먼저 확인하지 않는 경우에는 그렇지 않습니다.[많은 레거시 함수는 이러한 매개변수에 대한 유효한 입력을 기대하지만 정책은 다시 확인하는 것입니다.] 자체 방어가 아닌 방어로 표시된 함수를 설명하는 정적 분석 오류가 있습니까?

로부터 문서,

함수가 신뢰 경계에 나타나면 _Pre_defensive_ 주석을 사용하는 것이 좋습니다."방어적" 수정자는 특정 주석을 수정하여 호출 시점에서 인터페이스를 엄격하게 검사해야 하지만 구현 본문에서는 잘못된 매개변수가 전달될 수 있다고 가정해야 함을 나타냅니다.그 경우, ~ 안에 _Pre_defensive_는 호출자가 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_ 주석.그러나 Microsoft에는 내부적으로 사용하는 추가 및 확장 분석기가 있습니다.이는 주석을 활용할 수 있으며 향후 대중에게 공개될 수도 있습니다.

그래서 그것은 절충안입니다.선언이 너무 복잡하다고 생각되면 제거해도 실제로 해가 되는 것은 없습니다. _Use_decl_annotations_ 헤더에만 주석을 넣으면 됩니다.)한편, 이는 미래에 사용될 수 있으며 의도된 사용에 대한 문서로 사용될 수도 있습니다.

편집하다:에 관해서는 _In_defensive_(annotes), 이를 통해 다음을 적용할 수 있습니다. _Pre_defensive_ 모든 주석에 대한 주석( annotes).또한 이를 통해 주석을 다른 위치에 배치할 수 있습니다.

_In_defensive(_Pre_satisfies_(pInt != nullptr))
void fun3(int* pInt)
{
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top