C/C++ значение по умолчанию / значение, присвоенное переменной, никогда не используется
Мне нравится всегда инициализировать локальные переменные, например
int32_t result = 0;
Я думал, что это хороший стиль программирования, потому что "результат" никогда не может быть инициализирован, независимо от того, установлены ли следующие if-конструкции или нет.
Но теперь я пытаюсь использовать инструмент проверки статического кода (C_STAT для встроенного рабочего места IAR), и это жалуется на то, что в приведенной ниже функции правило MISRA-C++ 2008-01-06 ("не должно содержать экземпляров энергонезависимых переменных, которым даны значения которые впоследствии никогда не используются ") и MISRA C:2012 правило 2.2c (" без мертвых кодов ") и CWE 563 (" неиспользуемая переменная ") нарушаются.
// gets signal1 - signal2 (checks range of value)
int16_t getSignalDifferenceFromFloat(float signal1, int16_t signal2)
{
int32_t result = 0; // <-- this assignment makes the violation
// ... but I feel better with it
if (signal1 > 65535.0)
{
// because result cannot be smaller than the max value of TSignal
result = 32767;
}
else if (signal1 < -65535.0) // <-- here an else was missing
{
// because result cannot be larger than the min value of TSignal
result = -32768;
}
else
{
result = (int32_t)signal1 - (int32_t)signal2;
if (result < -32768)
{
result = -32768;
}
else if (result > 32767)
{
result = 32767;
}
}
return (int16_t) result;
}
Оригинальный вопрос: что вы думаете об этом?
Новые вопросы:
- Существуют ли хорошие стандарты кодирования, которые всегда требуют немедленной инициализации объявленных локальных переменных?
- Является ли средство проверки кода слишком педантичным (некоторые компиляторы не жалуются в этом месте, но будут жаловаться, что переменная будет полностью не использована)? Я делаю это годами, но не могу вспомнить, где я это видел.
3 ответа
Я согласен с MISRA.
Ненужная инициализация переменной может привести к небрежному коду, поскольку он побеждает инструменты, которые проверяют неинициализированные переменные.
В вашем конкретном случае вы могли бы локализовать result
в финал else
дело и возврат преждевременно в других случаях. Но это не всем по вкусу.
Большинство хороших статических анализаторов предоставят вам анализ потока данных, который предупредит вас о возможных путях, оставляющих неинициализированные переменные.
Если взять ваш пример, скажем, вы (случайно) пропустили одно из более поздних заданий, это не будет обнаружено SA:
/// gets signal1 - signal2 (checks range of value)
int16_t getSignalDifferenceFromFloat(float signal1, int16_t signal2)
{
int32_t result = 0; // <-- this assignment makes the violation
// ... but I feel better with it
if (signal1 > 65535.0)
{
// commented out this line
// No data-flow anomoly detected
// result = 32767;
}
// Snip rest of code
return (int16_t) result;
}
Рекомендации MISRA не идеальны, во всяком случае, но мы стараемся и не допускаем очевидных... и неинициализированные переменные довольно легко обнаружить - до тех пор, пока вы не попытаетесь решить проблему.
Это немного похоже на вставку, просто чтобы закрыть инструмент статического анализа......
[Посмотреть профиль для отказа от ответственности]
Статические анализаторы применяют правила, которые вы определяете - некоторые из этих правил будут конфликтовать, потому что вы должны установить их в соответствии с вашим локальным стандартом кодирования. Я предполагаю, что есть также правило, которое может быть включено или не включено, которое требует инициализации всех переменных; и вы не можете сделать оба.
Выберите неконфликтующий набор правил, который соответствует вашему предпочтительному стандарту. То, что вы выбираете, является вопросом мнения, поэтому не является действительным вопросом SO.