Вопрос

Я пробовал себя в Шина с помощью программы на языке Си, которую я недавно написал, я пытаюсь понять и удалить предупреждения, которые она выдает.Один, который я понимаю, но не могу понять, как его удалить, взят из следующего фрагмента кода:

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 недоволен тем, что функция может возвращать NULL, но в данном случае это имеет смысл.

Я пробовал использовать /@null , когда ложь@/ но, похоже, это работает только в том случае, если функция возвращает true / false, а также попыталась изменить код, чтобы использовать retVal, и попробовала оба /@нулевой@/ и /@relnull@/ перед объявлением, но они ничего не сделали.

(Просто в качестве дополнительного примечания, таблица занимает всего 20 больших банкоматов, так что нет смысла использовать умный алгоритм поиска.)

Это было полезно?

Решение

Вам следует дважды проверить использование /*@null@*/ перед объявлением.

В следующей компилируемой версии вашего примера предупреждение действительно удаляется (с использованием 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;
}

Если у вас все еще есть подобное предупреждение, может быть, оно касается другой части вашего кода?

Другие советы

splint -nullret скроет это предупреждение (глобально), которое может быть или не быть тем, что вы хотите сделать.В некоторых случаях, если только вы не конечно имея тип, возвращающий значение NULL, вы, вероятно, хотеть предупреждение.

Я протестировал пример Джерома, и он отключил предупреждение для этой конкретной функции.

Что бы вы ни делали, я бы настоятельно рекомендовал не встраивать коды splint непосредственно в исходный код, а вместо этого обернуть эту функциональность в макрос.

Например, в проекте Parrot у меня есть эти макросы

#  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 */

И затем используются макросы, чтобы мы могли использовать:

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

Если мы хотим изменить способ обработки аргументов ARGIN(), мы меняем это в одном месте.Мы также можем поддерживать несколько обозначений для нескольких инструментов или компиляторов.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top