Изменение типа одной переменной кардинально меняет размер компиляции
У меня есть набросок, содержащий следующий метод:
// Записывает нули на весь экран, очищая его:
void clearScreen(uint8_t val) {
setDrawArea(0x00, 0x7f, 0x00, 0x07); // полный экран
SSD1306.ssd1306_send_data_start();
for (int c = 0; c < 128 * 8; c++) {
SSD1306.ssd1306_send_byte(val);
}
SSD1306.ssd1306_send_data_stop();
}
Весь скетч компилируется с размером 6730 байт. Во время рефакторинга кода я по ошибке изменил "c" на uint8_t. После этого я скомпилировал в 4124 байта. Это происходит из-за того, что компилятор распознает, что условие цикла никогда не будет достигнуто, и отсекает весь код позади, или это какое-то странное событие оптимизации? Я спрашиваю, потому что не могу сейчас протестировать скетч.
@needfulthing, 👍1
1 ответ
Лучший ответ:
Не имея возможности доказать это (поскольку у меня нет ваших библиотек, а вы привели лишь небольшую часть наброска), я думаю, что происходит следующее:
user3629249 наполовину прав. Если изменить c
на тип uint8_t
, у него будет только 8 бит (отсюда и название), поэтому его максимальное значение будет 255. Когда вы добавите к этому значению 1, переменная переполнится и вернется к 0. Это нормальное поведение при переполнении, как при использовании регистров таймера Arduinos. (Здесь нет неопределенного поведения). Поэтому максимальное значение, которого может достичь c
, равно 255.
При сравнении с большим литералом значение c
повышается до правильного типа, так что два значения можно сравнивать. Но переменная, которая находится на максимуме 255, всегда меньше, чем 128*8. Так что у вас здесь бесконечный цикл. Компилятор может это увидеть и не включает функции из остальной части clearScreen()
, так как это недостижимый код.
В целом ваш код не будет работать так, как задумано с uint8_t
. Вам нужен больший тип, который может содержать весь диапазон, с которым вы работаете. И эта оптимизация не странная, а очень разумная, поскольку в этом случае вам действительно не нужна остальная часть clearScreen()
.
- Будет ли .ino-скетч ардуино компилироваться непосредственно на GCC-AVR?
- Использование std::list в программировании Arduino
- Управление сервоприводом с помощью ATtiny13A
- Оптимизация кода для ATtiny10
- Как уменьшить использование глобальных переменных? Attiny85
- помогите скомпилировать код для проекта флоры
- Как установить приложение + его конфигурацию на множество однотипных устройств? (ESP32)
- C++ против языка Arduino?