MISRA Нарушение 12.9 Операнд унарного минуса не подписан - PullRequest
4 голосов
/ 02 апреля 2020

В настоящее время я имею дело с некоторыми проблемами MISRA и поэтому пытаюсь понять правила целочисленного преобразования в C.

Я получаю нарушение MISRA- C 2004 rule 12.9 Унарный оператор минус не должен применяться к выражению, базовый тип которого без знака

в строке кода

signed long int test = -1;

Я понимаю, что нет отрицательной целочисленной константы "-1 ", а унарный минус применяется к целочисленной константе" 1 "(как указано в https://en.cppreference.com/w/c/language/integer_constant).

Однако целочисленная константа" 1 "относится к первому типу в list int , long int , long без знака int (до C99) , long long int (с C99)

Я работаю с Keil (ARM 32 бита) и установленным флагом --c99, в то время как MISRA- C 2004, похоже, основан на стандарте C90.

Так что, похоже, мой инструмент SCA предполагая, что константа "1" имеет тип unsigned long int (до C99) , но я не могу понять, почему она не будет оно в обычном int и, следовательно, должно быть подписано.

Чтобы удовлетворить инструмент SCA, необходимо кодировать

signed long int test = -1L;

или

signed long int test = -((signed long int) 1);

Это правильное поведение или я что-то здесь упускаю?

1 Ответ

5 голосов
/ 02 апреля 2020

Целочисленная константа "1", однако, имеет первый тип в списке int, long int, unsigned long int ...

Правильно. Целочисленные константы, такие как 1, относятся к типу int, а что касается MISRA- C, базовый тип также равен int. Это определение (MISRA- C: 2004 6.10.4)

Термин «базовый тип» определяется как описание типа, который будет получен при оценке выражения, если бы не эффекты интегрального продвижения.

Строка signed long int test = -1; соответствует MISRA- C: 2004 (и MISRA- C: 2012).

  • Выражение -1 не содержит в себе неявных рекламных акций. Интегральное продвижение не применяется.
  • Таким образом, -1 имеет базовый тип со знаком int и при назначении он неявно преобразуется в более широкий целочисленный тип с той же самой подписью, что хорошо.
  • Цель состоит в том, чтобы создать подписанную переменную, поэтому правило о суффиксе u не применяется.
  • Кроме того, правило 10.1 против неявных преобразований из так называемого «сложного выражения» в различные типы также не применимо, поскольку -1 является константным выражением, а не сложным выражением (см. MISRA- C: 2004 6.10.5).

Так что это еще одна ошибка инструмента. Кажется, что инструмент выбирает неверный базовый тип выражения, что может быть серьезной ошибкой.

signed long int test = -1L; не является обязательным для соответствия, хотя он также является совместимым кодом.

...