Буквальный ноль вместо предупреждения о нулевом указателе-константе от MISRA

У меня есть эта функция:

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 и почему?

4

Решение

поскольку nums является unsigned int, вам нужно будет сравнить с 0Uгде добавленная буква «U» указывает, что литерал является беззнаковым целым, в отличие от беззнакового целого.

Это ловит мою команду все время. Мы не понимаем, почему ноль должен быть помечен как неподписанный.

Кроме того, вы не имеете дело с указателями. Подпись функции, unsigned int&, указывает, что переменная будет передана по ссылке, а не по указателю. Вы будете изменять исходный объект, а не его копию.

4

Другие решения

Позвольте мне начать с того, что у меня нет опыта работы с 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 ++ неисправна и выдает неверные ошибки.
  • Конкретное правило MISRA-C ++ против буквального нуля, похоже, не имеет никакого смысла. Вы должны повысить отклонение в своей реализации MISRA от этого правила и полностью игнорировать правило, пока кто-то не сможет дать обоснование этому.
3

Я могу ошибаться, я не очень опытный в программировании, и, возможно, ответ немного запоздал, но я думаю, что ваш контролер 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) {
..
}
}

Проверьте, жалуется ли это после этого.

0
По вопросам рекламы [email protected]