Question

Donc, je suis raisonnablement familier avec l'aide de Microsoft Source d'Annotation de la Langue (la VS 2012-2013 saveur) pour décrire la fonction des contrats avec des pointeurs.

Une chose que je suis curieux de savoir, cependant, c'est que je m'attendais à un résultat différent avec _In_ _Pre_defensive_ que sans elle, pour le cas où l'appelant n'est pas de vérifier le pointeur de la première.[Beaucoup de notre héritage fonctions attendre d'entrée valide pour ces paramètres, mais la politique est double vérification.] Est-il une analyse statique d'erreur pour décrire une fonction marquée défensive ne défend pas lui-même?

À partir de la docs,

Si une fonction apparaît à une limite de confiance, nous vous recommandons d'utiliser le _Pre_defensive_ annotation."Défensif" modificateur modifie certaines annotations pour indiquer que, au moment de l'appel, l'interface doit être vérifiée strictement, mais dans la mise en œuvre du corps, il doit supposer que des paramètres incorrects peuvent être transmises.Dans ce cas, Dans _Pre_defensive_ est préféré à une limite de confiance pour indiquer que, bien que l'appelant un message d'erreur si elle tente de faire passer la valeur NULL, le corps de la fonction seront analysés comme si le paramètre peut être NULL, et toutes les tentatives de renvoi le pointeur sans d'abord vérifier la valeur NULL sera marqué.

Voici un petit programme de démonstration pour l'analyse de code.Tous les 4 de mes fonctions de montrer C6387 dans l'analyse statique, mais j'espérais voir une indication supplémentaire que ma "défense" de la fonction n'a pas fait la vérification de l'entrée en fun0().Est-il un avantage à ajouter ce qualificatif?- Il vraiment encombre de la déclaration, si elle n'aide pas, il est difficile de justifier le mettre là.

// 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;
}

Question Bonus:Je vois dans la sal.h il y a un _In_defensive_(annotes) annotation en tant que bien, mais je ne comprends pas comment l'utiliser.

Merci.

Était-ce utile?

La solution

AFAICT il n'existe actuellement aucune (public) différence lors de l'ajout de l' _defensive_ les annotations.Cependant, Microsoft a supplémentaires et accru les analyseurs de laquelle ils utilisent en interne.Ceux-ci pourraient utiliser les annotations, et peut obtenir aussi publié dans l'avenir.

C'est donc un compromis.Si vous pensez qu'ils l'encombrement de la déclaration de trop, il n'y a pas de réel danger pour les enlever (à noter toutefois que, par le biais _Use_decl_annotations_ vous avez seulement besoin de mettre de l'annotation dans l'en-tête).D'autre part, dans l'avenir, cela peut s'habituer, et il peut également être utilisé que de la documentation sur l'utilisation prévue.

EDIT:Comme pour _In_defensive_(annotes), il permet d'appliquer la _Pre_defensive_ annotation à toutes les annotations (en annotes).Aussi, cela permet de placer l'annotation dans un endroit différent, c'est à dire

_In_defensive(_Pre_satisfies_(pInt != nullptr))
void fun3(int* pInt)
{
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top