Remover nulo avisos em Tala
-
21-09-2019 - |
Pergunta
Eu tenho tentado Tala com um programa em C eu escrevi recentemente e tentar entender e remover os avisos que ele dá.Eu entendo, mas não consigo entender como remover vem o seguinte trecho de código:
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;
}
Tala não é feliz que a função pode devolver um valor NULO, mas neste caso faz todo o sentido.
Eu tentei usar /@nullwhenfalse@/ mas parece funcionar somente se a função retorna true/false e também tentou alterar o código para usar um retVal e tentei tanto /@null@/ e /@relnull@/ na frente de declaração, mas estes não fizeram nada.
(Apenas como uma nota, a tabela é de apenas 20 grandes atm, de modo nenhum ponto em uso inteligente do algoritmo de pesquisa.)
Solução
Você deve verificar o uso de /*@null@* / na frente da declaração.
Na versão compilável a seguir do seu exemplo, ele remove o aviso (usando o splint 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 você ainda tem um aviso semelhante, poderia ser outra parte do seu código?
Outras dicas
splint -nullret
irá esmagar esse aviso (globalmente) que pode ou não ser o que você deseja fazer. Em alguns casos, a menos que você seja claro ter um tipo de retorno de tipo nulo está correto, você provavelmente querer O aviso.
Testei o exemplo de Jerome e ele silenciou o aviso para essa função específica.
Tudo o que você fizer, eu sugiro fortemente a não incorporação de tala de códigos diretamente na fonte, mas em vez disso, envolver essa funcionalidade em uma macro.
Por exemplo, sobre o projeto Papagaio, eu tenho essas 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 */
E, em seguida, as macros são usadas de modo que podemos usar:
void copy_string( ARGOUT(char *target), ARGIN(const char *source ) ) ...
Se queremos mudar a forma como ARGIN() argumentos são tratados, podemos alterá-lo de um lugar.Também podemos suportar várias notações para várias ferramentas e compiladores.