Чтобы понять, что послужило причиной предупреждения, вы должны понять (или хотя бы знать) о несколько загадочных и иногда удивительных правилах продвижения шрифтов C.
C по битам арифметические c операторы работают с int
или unsigned int
или большими типами, поэтому при представлении с операндами меньшего типа происходит неявное повышение:
Рассмотрим этот «эксперимент» например:
#include <stdint.h>
#include <stdio.h>
int main()
{
uint8_t a ;
uint8_t b ;
printf( "sizeof(a) = %zu\n", sizeof(a) ) ;
printf( "sizeof(b) = %zu\n", sizeof(b) ) ;
printf( "sizeof(a | b) = %zu\n", sizeof(a | b) ) ;
printf( "sizeof((uint8_t)(a | b)) = %zu\n", sizeof((uint8_t)(a | b)) ) ;
printf( "sizeof(a >> 3) = %zu\n", sizeof(a >> 3) ) ;
printf( "sizeof((uint8_t)(a >> 3)) = %zu\n", sizeof((uint8_t)(a >> 3)) ) ;
return 0;
}
Выход (где int
является 32-разрядным):
sizeof(a) = 1
sizeof(b) = 1
sizeof(a | b) = 4
sizeof((uint8_t)(a | b)) = 1
sizeof(a >> 3) = 4
sizeof((uint8_t)(a >> 3)) = 1
Так в первом случае:
AP_component_require_auth |= (uint8_t)apX_compY_bitmask;
Приведение uint8_t
не имеет смысла, поскольку это уже тот тип, и, конечно, не побеждает неявное преобразование.
Я не знаком с CERT- C или Coverity, но в аналогичных инструментах, которые я использовал, может использоваться неявное приведение, чтобы утверждать, что выражение является преднамеренным:
AP_component_require_auth = (uint_8_t)(AP_component_require_auth | apX_compY_bitmask) ;
y_loc = (uint8_t)(major_revision >> 3) ;
Как вы можете видеть, это невозможно решить с помощью |=
, потому что вы не можете затем привести результат выражения |
перед присваиванием.
Однако часто лучше поддерживать соглашение о типе и избегать неявного или явное преобразование и использование int
, unsigned
или целочисленного типа равного / большего размера, если нет веской причины использовать меньший тип.
В обоих случаях проблема заключается в присвоении int
типоразмер до uint8_t
. Хотя первое предупреждение несколько сбивает с толку - возможно, из-за использования |=
- предотвращение его формирования представлением неявно приведенного выражения; вы должны получить ту же ошибку без ненужного приведения я думаю. Инструмент анализа stati c, с которым я знаком, сказал бы что-то вроде:
неявное преобразование в меньший тип в присваивании
в обоих этих случаях, т.е. думаю, намного яснее.
Предупреждение о скрытности является кратким и минимальным; если вы go прямо применяете к стандарту, который он применяет, он гораздо более явный и дает обоснование, примеры и решения: https://wiki.sei.cmu.edu/confluence/display/c/INT31-C.+Ensure+that+integer+conversions+do+not+result+in+lost+or+misinterpreted+data