У меня есть эта функция:
void InitS(unsigned int &numS){
// this function returns a container for unsigned int
// but it has a cast for int
numS = props.numOfS();
if (numS > 0) {
..
}
}
Он компилируется, но выдает мне предупреждение MISRA:
MISRA-C ++ Правило 4-10-2 (обязательно): Литеральный ноль (0) не должен использоваться в качестве константы нулевого указателя.
Сейчас если numShots
был «реальный» указатель, я мог бы изменить 0
в NULL
, Но numShots
это ссылка, и я должен относиться к нему, как это было int
,
Чего хочет MISRA и почему?
поскольку nums
является unsigned int
, вам нужно будет сравнить с 0U
где добавленная буква «U» указывает, что литерал является беззнаковым целым, в отличие от беззнакового целого.
Это ловит мою команду все время. Мы не понимаем, почему ноль должен быть помечен как неподписанный.
Кроме того, вы не имеете дело с указателями. Подпись функции, unsigned int&
, указывает, что переменная будет передана по ссылке, а не по указателю. Вы будете изменять исходный объект, а не его копию.
Позвольте мне начать с того, что у меня нет опыта работы с MISRA-C ++, но у меня достаточно MISRA-C.
У MISRA-C есть некоторые опасения по поводу безопасности типов, которые также применимы к MISRA-C ++. Одной из таких проблем является то, что не должно происходить неявное продвижение по типу. Это серьезная проблема, неявные продвижения по типу сложно понять и привести к ошибкам. Большинство программистов на C и C ++ неожиданно даже не знают, как работают неявные продвижения типов. Чтобы обучить программистов этому и защититься от таких ошибок, существует множество правил MISRA, касающихся неявных преобразований / продвижений типов.
Одно из таких правил применяет суффикс ‘u’ ко всем целочисленным литералам. Обоснование этого правила состоит в том, чтобы уточнить, что большие литералы, близкие к максимальному значению int, являются беззнаковыми, например, тип литерала 0x80000000
не является очевидным для читателя. (Я лично считаю это правило излишним и несколько ошибочным, поскольку все неявные опасности преобразования уже подпадают под другие правила.)
Существует также другое правило, гласящее, что проверки указателя на NULL должны быть явными. Вам не разрешено писать if(ptr)
Лучше напиши if(ptr!=NULL)
, Обоснование — удобочитаемость и безопасность типов.
И, очевидно, существует такое правило, что указатели не следует сравнивать с нулевым литералом. Я не понимаю причины этого, якобы они боятся, что вы смешаете указатели и простые целочисленные переменные. Очевидно, они приняли решение отклониться от амбиций Бьярна Страуструпа по удалению мистификации нулевых указателей в C ++. Согласно Страуструпу, NULL и 0 всегда эквивалентны в C ++ (хотя C ++ 11 будет иметь ключевое слово nullptr, решающее этот беспорядок раз и навсегда).
Никто Вышеуказанные правила имеют отношение к коду в вашем примере! Вы сравниваете ссылку с нулевым литералом, что совершенно безопасно. Программа проверки MISRA может жаловаться на отсутствие суффикса ‘u’, но ваша программа проверки не сделала этого.
Мои выводы:
Я могу ошибаться, я не очень опытный в программировании, и, возможно, ответ немного запоздал, но я думаю, что ваш контролер MISRA-C думает «он сравнивает переменную типа« ссылка »с литеральной константой, поэтому он должен проверять NULL-ссылку «, хотя это не совсем верно для References, но вы можете попробовать присвоить возвращаемое значение функции props.numOfS () новой переменной, а затем выполнить присвоение переменной, на которую ссылается numS, в другая строка при сравнении новой переменной.
то есть
void InitS(unsigned int &numS){
unsigned int foo;
foo = props.numOfS(); //this function returns a container for unsigned int but it has a cast for int
numS = foo;
if (foo > 0) {
..
}
}
Проверьте, жалуется ли это после этого.