MISRA C 2004 10.1, подпись printf% x

Я получаю ошибки от нашего инструмента статического анализа по поводу следующего фрагмента:

uint8_t value = 24U;
char buffer[512];
int chars_printed = snprintf(buffer, sizeof(buffer),
                             "The value in hex is 0x%02hhX\r\n",
                             value);

Ошибка:

Нарушение правила 10.1 MISRA-2004: неявное преобразование непостоянного выражения в аргумент функции. Преобразование «значения» с базовым типом «unsigned char» (8 бит, без знака) в тип «int» (32 бита, со знаком).

Какой подписи и разрядности ожидает MISRA от спецификатора "% X"?

Считается, что "% X" берет unsigned int со страницы cppreference page. .

В программе проверки MISRA C 2004 компилятора IAR нет ошибок.
Эта ошибка от Coverity.


person Thomas Matthews    schedule 27.04.2015    source источник
comment
snprintf принимает список аргументов с переменным числом аргументов, поэтому value будет продвигаться целиком. Вы можете отключить предупреждение, применив (unsigned)value   -  person Praetorian    schedule 28.04.2015
comment
@Praetorian, это не объясняет проблему подписи. Меня устраивает то же продвижение подписи к большему типу, но откуда этот тип int32_t? Это список вариативных аргументов? Я не вижу никаких определений параметров ни в одном из моих ресурсов языка C.   -  person Thomas Matthews    schedule 28.04.2015
comment
Если в списке аргументов с переменным числом аргументов передать тип меньше int, он будет повышен до int. Прочтите раздел преобразований по умолчанию, здесь.   -  person Praetorian    schedule 28.04.2015
comment
У вас есть ссылка на этот источник, pdf?   -  person 2501    schedule 28.04.2015
comment
Типы stackoverflow.com/q/1255775/995714, более узкие, чем int, будут преобразованы в int   -  person phuclv    schedule 28.04.2015
comment
Аргументы с переменным числом аргументов вызывают продвижение аргумента по умолчанию, которое, в свою очередь, вызывает целочисленное продвижение, о чем заботится правило MISRA. Хотя функции с вариативными аргументами и stdio.h в любом случае запрещены MISRA-C.   -  person Lundin    schedule 28.04.2015


Ответы (1)


Проблема в том, что семейство printf неявно продвигает все аргументы небольшого целочисленного типа до int. Неявное продвижение типа такого рода запрещено правилом 10.1, и именно поэтому вы получаете ошибку нарушения MISRA. Это не имеет ничего общего со спецификатором формата.

Для соответствия MISRA просто явно укажите значение перед передачей его функции: (uint32_t)value.

Также обратите внимание, что MISRA не позволяет использовать stdio.h в производственном коде.

person Lundin    schedule 28.04.2015
comment
Кстати, в данном случае Coverity, похоже, работает лучше, чем IAR. - person Lundin; 28.04.2015
comment
На самом деле, MISRA разрешает использование, если разница задокументирована. Мы используем строковые функции printf и scanf; поскольку мы не хотим писать и тестировать свои собственные. - person Thomas Matthews; 28.04.2015
comment
@ThomasMatthews Документирование всего плохо определенного поведения и всех других ловушек, связанных с функциями stdio.h, кажется довольно монументальной задачей ... вам придется написать книгу. Это хорошее правило, использование этих функций в производственном коде для критически важной системы - очень сомнительная практика. Что касается sprintf / sscanf, развертывание вашей собственной версии занимает меньше часа работы, учитывая, что вы используете их только для преобразования в / из целых чисел (а не с плавающей точкой и т. Д.). - person Lundin; 28.04.2015