2011-09-20 3 views
0

J'ai l'exemple de code suivant et je voudrais savoir quel type d'annotations je peux utiliser pour les éviter.Annotations pour le Déréférencement NULL dans Prefast et la compilation sur GCC

int Function(classA* pInput) { 
    if (pInput == NULL) { 
     classA::Create(pInput); 
    } 

    return pInput->value; 
} 

Le problème est que depuis PREfast évalue que la fonction qu'il ne sait pas que le pointeur Create initialise.

Je pensais que je pourrais le résoudre en utilisant l'annotation __out dans le fichier d'en-tête pour classA::Create mais cela n'a pas fonctionné.

Je me demande s'il y a une bonne alternative à __analysis_assume partout dans le code de sorte que le préfabriqué le prenne dans la définition de la fonction.

Deuxièmement, Je me demandais comment j'installerais ma configuration de construction pour que je puisse construire mon code nativement sur Linux ou avec GCC avec ces directives de préprocesseur. Est-ce que je devrais vérifier si c'est sur une construction de LINUX et puis ajouter ces annotations en tant que macros vides?

+0

j'ai vu ce style d'indentation un _lot_ au cours de la dernière semaine. Est-ce à partir d'un manuel? –

+0

Il n'y a rien de mal à ce code supposant 'create' est une méthode statique qui affecte réellement et initialiser l'objet. Avez-vous une erreur? – AJG85

+0

Je voudrais faire une motion pour brûler ce style d'indentation avec le feu. –

Répondre

2

MSalter’s answer ressemble beaucoup à la réponse technique correcte. Heureusement je ne connais pas SAL, donc je ne peux pas le dire avec certitude, mais ça ressemble à la solution au niveau technique.

Cependant, je vous recommande simplement de réécrire votre code actuel & hellip;

int Function(classA* pInput) { 
    if (pInput == NULL) { 
     classA::Create(pInput); 
    } 

    return pInput->value; 
} 

as & hellip;

int Function(classA* pInput) { 
    if (pInput == NULL) { 
     pInput = classA::Create(); 
    } 

    return pInput->value; 
} 

La question principale est de savoir si vous êtes fuite un objet créé dynamiquement, ou non. Cela dépend beaucoup de ce que fait la méthode Create. Mais il semble que vous fuyez.

Et dans ce cas, où Create ne fait que allouent dynamiquement un objet par défaut initialisé classA, alors voici comment vous pouvez le faire de manière plus sûre et plus efficacement:

int Function(classA* pInput) { 
    if (pInput == NULL) { 
     return classA().value; 
    } 

    return pInput->value; 
} 

Enfin, pour un nettoyage total envisager comment se débarrasser des pointeurs bruts inutiles. Parce que les pointeurs bruts créent des problèmes (votre code n'étant qu'un très petit exemple de cela). Ensuite, vous pouvez faire des choses comme ceci:

int function(ClassA const& anObject = ClassA()) 
{ 
    return anObject.value; 
} 

Essentiellement ceci est une solution de niveau C++, par opposition au niveau C du code d'origine. J'ai donc changé aussi la convention de dénomination pour refléter le focus beaucoup plus fort sur les types au niveau C++. Ici les types ont une première lettre majuscule, et une simple fonction a une première lettre minuscule.

C'est plus simple, c'est plus sûr, c'est encore plus efficace.

Et – au niveau C++ vous n'avez généralement pas à lutter avec des notations SAL ridicules. :-)

Salutations & hth.,

+0

+1 pour la détection des fuites, +1 pour suggérant d'utiliser une référence plutôt qu'un pointeur, -1 pour ne pas suggérer de lancer une exception dans le cas d'un pointeur nul. Net: +1. –

+0

@ David: J'ai choisi de traiter le code comme intentionnel, et dans ce cas un nullpointer n'est pas une erreur mais la façon conçue pour obtenir une valeur par défaut. Maintenant, donnez-moi l'upvote supplémentaire! –

+0

J'ai essayé mais j'ai reçu ce message: "* Vous avez voté pour cette réponse il y a 1 heure Votre vote est maintenant verrouillé sauf si cette réponse est éditée. *" –

1

On dirait SA manque [Post(Null=No)] sur le paramètre classA*& de classA::Create(classA*)

+0

Je ne peux pas simplement ajouter __out à :: Create? – Setheron

+0

Je ne pense pas. '__out' garantit simplement que' pInput' a une valeur _a_, et non qu'elle a une valeur non nulle. Notez que '[]' est [la nouvelle syntaxe] (http://blogs.msdn.com/b/michael_howard/archive/2006/05/19/602077.aspx) – MSalters