AlexGyver / GyverCore

Быстрое ядро для Arduino IDE
https://alexgyver.ru/gyvercore/
GNU Lesser General Public License v3.0
127 stars 13 forks source link

Инициализация неинициализированных переменных #19

Closed ilyavennik closed 2 years ago

ilyavennik commented 3 years ago

В C++ чтение неинициализированных переменных является неопределённым поведением. Стоит отметить, что в исправленных местах кода ядра логических ошибок нет, поэтому, такого чтения не происходит. Однако отсутствие начальной инициализации делает код хрупким.

AlexGyver commented 3 years ago

Глобальные всегда по нулям =)

ilyavennik commented 3 years ago

Глобальные всегда по нулям =)

Верно. Но PR речь идёт о локальных переменных и поле класса (они не глобыльные).

AlexGyver commented 3 years ago

Справедливо. Но эти переменные не читаются до того, как в них запишутся данные. Иначе ничего бы не работало

ilyavennik commented 3 years ago

Всё так. Только вот проблема в том, что компилятор в таких случаях достаточно тупой, чтобы понять это самостоятельно.

for (byte i = 0; i < 10; i++) {
    bytes[i] = data % 10;
    data /= 10;

    if (data == 0) {
        amount = i;
        break;
    }
}

Внутри цикла, if не имеет ветки else. Даже несмотря на то, что логически мы всегда свалимся в if. У компилятора недостаточно информации об этом, и он кидает предупреждение. Также, компилятор может использовать эту информацию для своих оптимизаций, что уже может привести к неопределённому поведению. Ну и в конце концов, код точно сломается если изменить тип аргумента функции или размер массива.

P.S. А break на самом деле то и не нужен. :)

AlexGyver commented 3 years ago

А какой компилятор видит такие косяки?

ilyavennik commented 3 years ago

Ну это не совсем компилятор, скорее внешний инструмент, – статический анализатор кода cppcheck.

ilyavennik commented 2 years ago

Закрываю из-за неактуальности.