2016-08-24 16 views
1

Я прочитал связанные вопросы к этому предупреждению Lint о подозрительном усечении, но здесь это чисто случай C.Lint Warning: # 647: Подозрительное усечение

Следующая строка, где Warning #647 всплывает:

pCont->sig -= (signed int64_t)((sub2 << 8)/pCont->freq + 1); 

, где pCont->sig также 64-битный (тип signed int64_t), и оба sub2 и freq 32 бит без знака. Все это скомпилировано с помощью armcc.

Уже пробовал, без успеха, чтобы отличить 1 с неподписанным 32 бит, но проблема не устранена.

Любая идея о том, что я могу попробовать, или что здесь происходит не так?

+2

Не связанный с вашей проблемой, но 'int64_t' уже определен как' signed', вам не нужно указывать 'signed' снова при его использовании. См. [эта целая ссылка с фиксированной шириной] (http://en.cppreference.com/w/c/types/integer). –

+2

Вам нужно: '((int64_t) sub2 << 8)/pCont-> freq + 1'? –

+1

Основные вопросы, на которые вы должны ответить сами: «Почему вы используете подписанный тип для хранения значения, когда он никогда не может быть отрицательным?» И «почему вы храните его как 63-битное значение, когда выражение никогда не может выдавать более 32 действительных битов?» И не помешает подумать о том, «Что происходит, когда sub2 слишком велик и значение переполняется?» Только после того, как вы скажете: «Я хотел это сделать!» вы можете подавить предупреждение. –

ответ

4

От this reference about the warning

Например:

(long) (n << 8) 

может вызвать это сообщение, если п беззнаковое целочисленное значение, в то время как

(long) n << 8 

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

Это, кажется, соответствует вашему случаю точно, а также показать вам, как это исправить.

+0

Предупреждение 'lint' исчезло! Ваше объяснение понятно. Я счастлив; мой босс счастлив; мой коллега QA счастлив :-) –