8
votes

En utilisant "affirmer" avec des pointeurs en C ++

Quand devons-nous utiliser "affirmer" pour les pointeurs en C ++ et quand ils sont utilisés, comment sont-ils les plus couramment mis en œuvre?


0 commentaires

7 Réponses :


14
votes

Généralement, vous utiliseriez une affirmation pour vérifier une condition qui, si FALSE, indiquerait un bogue dans votre application. Donc, si un pointeur nul ne devrait pas jamais être rencontré à un moment donné de l'application, sauf s'il y a un bogue, alors affirmez cela. Si cela pourrait être rencontré en raison d'une entrée non valide, vous devez effectuer une manipulation correcte d'erreur.


1 commentaires

Si un pointeur ne doit jamais être nul, vous voudrez peut-être penser à la transformer en une référence (si possible, bien sûr).



7
votes

Vous ne devez pas besoin d'utiliser Aster sur des pointeurs du tout. L'idée est de vous assurer de ne pas planter de casser lors de la déséroférance de vos indicateurs quand ils sont nuls.

Vous pouvez le faire avec assert mais ce n'est pas un moyen très professionnel de gérer des erreurs comme celle-ci Invariably termine le programme - pas une bonne idée si l'utilisateur ne l'a pas fait, par exemple, enregistré ses trois dernières heures d'entrée de données.

Ce que vous devriez faire avec des pointeurs est Pour les vérifier pour NULL-NESS et échouer gracieusement. En d'autres termes, demandez à votre fonction de renvoyer une erreur d'une sorte ou ne faites rien (tout le monde ne sera pas d'accord avec cette approche, mais il est parfaitement acceptable s'il est documenté).

Le affirme On entend à mon avis pour attraper des problèmes au cours du développement, c'est pourquoi vous trouverez ASSERT n'entraîne rien dans la libération sous certains compilateurs. Il est pas un substitut de la programmation défensive.

sur la façon de le faire: xxx

mais ce serait mieux fait comme: xxx

en d'autres termes, même si votre "contrat" ​​(API) indique que vous n'êtes pas autorisé à recevoir des pointeurs NULL, vous devez toujours les gérer gracieusement. Une vieille citation: être conservatrice dans ce que vous donnez, libéral dans ce que vous acceptez (paraphrasé).


3 commentaires

D'autre part, se briser et perdre 3 heures de travail de l'utilisateur est préférable d'essayer de "contourner" un problème et de corrompre 3 semaines.


@Anon, je crois que cela serait couvert par le "gracieusement" :-) évidemment, vous devez le faire droit . ASSERTS N'aidera pas votre logiciel sur le terrain un petit peu de petit peu s'il est désactivé dans le code sans débogage. Les affirmations sont pour le développement et non la production (sauf si vous êtes l'un de ces types qui n'envoie jamais de code de débogage sur le terrain de toute façon).


C'est là que les macros sont utiles: ASSERT peut produire un noyau en mode de débogage et une exception en mode de sortie :)



3
votes

ASSERT Les déclarations sont excellentes comme "documentation forcée" - c'est-à-dire qu'ils disent au lecteur quelque chose à propos du code ("Cela ne devrait jamais arriver") puis l'applique en vous informant si elles ne sont pas vraies.

Si c'est quelque chose que pourrait em> se produire (entrée non valide, mémoire non capable d'être attribuée), c'est pas fort> un temps d'utilisation de l'ASSERT. Les affirmations sont seulement em> pour des choses qui ne peuvent pas se produire si tout le monde obéissait des pré-conditions et tels. P>

Vous pouvez le faire donc: P>

ASSERT(pMyPointer);


1 commentaires

(Au cas où tout le monde se demande, les Allcaps affirment est la macro Microsoft Assert Macro et minuscule Aster est standard C.)



0
votes

J'utiliserais une affirmation où un pointeur nul ne provoquerait pas immédiatement un crash, mais pourrait entraîner une erreur méprise plus tard, c'est difficile à repérer.
EG:

ASSERT(p);   
strcpy(p, "hello");


0 commentaires

2
votes

De l'expérience si vous affirmez sur des conditions nulles qui devraient jamais arriver dans des conditions normales que vous programmez est dans un très mauvais état. La récupération de cette condition null sera plus susceptible que de ne pas masquer le problème initial.

sauf si vous codez avec une garantie d'exception à l'esprit ( Linky ) Je dis le laisser Crash, alors vous savez que vous avez un problème.


1 commentaires

Je dirais: "Ne devriez jamais arriver dans aucune condition".



0
votes

en C, il s'agit également de la fonction .. En mode de débogage, si affirment (x), X condition est fausse, il apparaît une alerte ... Mais rappelez-vous que cela ne fonctionne que dans le mode de débogage ... En mode de sortie, toutes les fonctions d'affirmation sont toutes ignorées


0 commentaires

0
votes

Les assertions sont utilisées pour définir la manière dont le programme devrait fonctionner. Cela étant dit, l'utilisation la plus courante de l'affirmation () S Lorsque le traitement des pointeurs est soit constitué d'une valeur valide (non nulle et de mémoire valide) ou que leur état interne est valide s'ils pointent sur un objet / instance de classe, par exemple.

Les assertions ne sont pas destinées à remplacer ou à agir comme code de condition d'erreur, mais plutôt à appliquer des règles que vous placez sur le fonctionnement de votre code, telles que quelles conditions doivent être à des moments donnés à temps. P>

Par exemple, P>

    class A
    {
    public:
        A(wchar_t * wszName)
        {
             _cch = 0;
             _wszName = wszName;
        }
        // Invariant method to be called at times to verify that the
        // internal state is consistent.  This means here that the
        // internal variable tracking the length of the string is
        // matching the actual length of the string.
        void Invariant()
        {
            Assert(pwszName != nullptr);
            Assert(_cch == wcslen(pwszName));
        }

        void ProcessABunchOfThings()
        {
            ...
        }
    protected:
        int _cch;
        wchar_t * pwszName;
    }

    // Call to validate internal state of object is consistent/ok
    A a(L"Test Object");
    a.Invariant();
    a.ProcessABunchOfThings();
    a.Invariant();


0 commentaires