Question

J'ai essayé Splint avec un programme C j'ai écrit récemment et essayer de comprendre et de supprimer la il donne des avertissements. Un je comprends, mais ne comprends pas comment l'enlever vient de l'extrait de code suivant:

static MyType_t *findById(const int id)
{
    int i;

    for (i = 0; i < MY_ARR_SIZE; i++) {
            if (my_arr[i].id == NOT_SET) {
                    /* Items are sorted so that items with 
                    NOT_SET as ID are at the end of the array */
                    break;
            }
            if (my_arr[i].id == id) {
                    return &(my_arr[i]);
            }
    }
    return NULL; 
}

Splint est pas heureux que la fonction peut retourner NULL, mais dans ce cas, il est parfaitement logique.

J'ai essayé d'utiliser / @nullwhenfalse @ / mais il semble fonctionner que si la fonction retourne true / false et a également essayé de changer le code d'utiliser un retVal et a essayé à la fois / @ null @ / et / @relnull @ / devant la déclaration, mais ceux-ci ne faisaient rien.

(Comme un côté note, la table est seulement 20 atm grand, donc inutile d'utiliser un algorithme de recherche intelligente.)

Était-ce utile?

La solution

Vous devriez revérifier l'utilisation de / * @ null @ * / en face de la déclaration.

Dans la version compilable suivante de votre exemple, il ne supprime l'avertissement (en utilisant attelle 3.1.2):

typedef struct { int id; } MyType_t;
#define NOT_SET -1
#define MY_ARR_SIZE 20
static MyType_t my_arr[MY_ARR_SIZE];

/*@null@*/ static MyType_t *findById(const int id)
{
    int i;
    for (i = 0; i < MY_ARR_SIZE; i++) {
            if (my_arr[i].id == NOT_SET) {
                    /* Items are sorted so that items with 
                    NOT_SET as ID are at the end of the array */
                    break;
            }
            if (my_arr[i].id == id) {
                    return &(my_arr[i]);
            }
    }
    return NULL;
}

int main() {
    (void)findById(10);
    return 0;
}

Si vous avez encore un avertissement similaire, pourrait-il être d'une autre partie de votre code?

Autres conseils

splint -nullret écrasera cet avertissement (globalement) qui peut ou peut ne pas être ce que vous voulez faire. Dans certains cas, à moins que vous êtes que d'avoir un NULL de retour de type est correct, vous avez probablement voulez l'avertissement.

Je l'ai testé l'exemple de Jérôme, et il a fait taire l'avertissement pour cette fonction particulière.

Quoi que vous fassiez, je suggère fortement ne pas intégrer les codes d'attelle directement dans la source, mais plutôt envelopper cette fonctionnalité dans une macro.

Par exemple, sur le projet Parrot, j'ai ces macros

#  define ARGIN(x)                    /*@in@*/ /*@notnull@*/
#  define ARGIN_NULLOK(x)             /*@in@*/ /*@null@*/
    /* The pointer target must be completely defined before being passed */
    /* to the function. */

#  define ARGOUT(x)                   /*@out@*/ /*@notnull@*/
#  define ARGOUT_NULLOK(x)            /*@out@*/ /*@null@*/
    /* The pointer target will be defined by the function */

Et puis macros sont utilisées pour que nous puissions utiliser:

void copy_string( ARGOUT(char *target), ARGIN(const char *source ) ) ...

Si nous voulons changer la façon dont les arguments Argin () sont traités, nous changeons un seul endroit. Nous pouvons également prendre en charge plusieurs notations de plusieurs outils ou compilateurs.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top