#c #pthreads #conditional #mutex #splint
#c #pthreads #условные операторы #мьютекс #splint
Вопрос:
У меня есть следующий код
static pthread_mutex_t watchdogMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t watchdogCond = PTHREAD_COND_INITIALIZER;
и я получаю следующие ошибки / предупреждения при использовании Splint
Статический watchdogCond._data._mutex, инициализированный нулевым значением: watchdogCond._data._mutex = (void )0 Ссылка без нулевой аннотации присваивается или инициализируется НУЛЕМ. Используйте /@null@*/, чтобы объявить ссылку как возможно нулевой указатель. (Используйте -nullassign, чтобы запретить предупреждение)
В чем проблема с этим и представляет ли это реальную опасность?
Ответ №1:
Похоже, что у splint проблема с явной инициализацией указателей как null. и ему нужен какой-то комментарий с переопределением аннотации, чтобы отключить предупреждение. Я бы просто последовал его совету и использовал -nullassign
опцию, чтобы отключить это предупреждение. Нет ничего плохого или вредного в том, что делает ваш код, или в том, как реализация определила макросы инициализатора. Это просто у splint иррациональные страхи.
Комментарии:
1. Спасибо. В Spint что-то говорится о том, что после этой ошибки, о которой я упоминал выше, проверка источника не может продолжаться.
2. Используйте
-nullassign
опцию, чтобы отключить эту проверку.
Ответ №2:
Кажется, что pthread_mutex_t
это непрозрачный указатель (вы могли бы отследить typedef
, чтобы выяснить). В Splint указатели не обнуляются по умолчанию. Если вы хотите иметь указатель с возможностью обнуления, вы должны объявить его с семантической аннотацией /*@null@*/
, например:
char * ptr1;
/*@null@*/ char * ptr2;
ptr1 = NULL; /* warning: implicitly not-nullable pointer */
ptr2 = NULL; /* OK: explicitly nullable pointer */
Согласно руководству, существует 3 варианта, касающиеся нулевого состояния:
null
Возможно, нулевой указатель.notnull
Ненулевой указатель.relnull
Ослабьте проверку на нуль. Нет ошибок, когда ему присваивается значение NULL или когда он используется в качестве ненулевого указателя.
Преимущество использования указателей, не обнуляемых, заключается в том, что вам не нужно проверять их каждый раз, когда вы получаете один из них. Например, вы могли бы аннотировать параметр функции как /*@notnull@*/
, и тогда вам не требуется проверять if(pointer == NULL)
, прежде чем разыменовывать его. Это сокращает проверку и упрощает ваш код.
Опасность игнорирования этих предупреждений заключается в том, что, если вы сообщаете Splint, что определенный указатель не может быть нулевым, и позже вы пытаетесь присвоить NULL
ему, этот нулевой указатель может в конечном итоге разыменоваться, и программа может завершиться сбоем.
На мой взгляд, ваша фактическая проблема заключается в политике Splint, которая рассматривает все указатели неявно как ненулевые. Это вынуждает вас аннотировать все ваши указатели, возможно, нулевые.