Rimozione avvertenze nulli in stecca
-
21-09-2019 - |
Domanda
Ho cercato stecca con un programma C Recentemente ho scritto e cercando di capire e rimuovere la avvertimenti che dà. Una Capisco, ma non riesco a capire come rimuoverlo deriva dal seguente frammento di codice:
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;
}
stecca non è felice che la funzione può restituire NULL, ma in questo caso ha perfettamente senso.
Ho provato ad utilizzare / @nullwhenfalse @ / ma sembra funzionare solo se la funzione restituisce vero / falso e anche cercato di cambiare il codice per utilizzare un retVal e provato sia / @ null @ / e / @relnull @ / di fronte della dichiarazione, ma questi non ha fatto nulla.
(Proprio come un lato nota, la tabella è solo il 20 atm grande, quindi nessun punto nel usando un algoritmo di ricerca intelligente.)
Soluzione
Si dovrebbe controllare due volte l'uso di / * @ * @ nullo / di fronte alla dichiarazione.
Nella seguente versione compilabile del vostro esempio, lo fa rimuovere l'avviso (utilizzando stecca 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;
}
Se avete ancora un avviso simile, potrebbe essere di un'altra parte del codice?
Altri suggerimenti
splint -nullret
sarà schiacciare quell'avvertimento (a livello globale), che può o non può essere quello che vuoi fare. In alcuni casi, se non si è che avendo un NULL tipo di ritorno è corretto, probabilmente volete il messaggio di avviso.
Ho testato l'esempio di Girolamo, e lo ha fatto mettere a tacere l'avviso per quella particolare funzione.
Qualunque cosa facciate, vi consiglierei vivamente di non incorporare i codici stecca direttamente nella sorgente, ma invece avvolgere tale funzionalità in una macro.
Ad esempio, nel corso del progetto Parrot, ho queste macro
# 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 */
E poi sono utilizzate le macro in modo che possiamo utilizzare:
void copy_string( ARGOUT(char *target), ARGIN(const char *source ) ) ...
Se vogliamo cambiare il modo Argin () argomenti vengono gestiti, la cambiamo un unico luogo. Possiamo anche supportare più notazioni per più strumenti o compilatori.