Я использую C++ для проекта низкоуровневой прошивки микроконтроллера. Некоторое время все было хорошо, размер кода оставался очень небольшим, пока я не представил следующую строку кода:
Код: Выделить всё
uint8_t index = __builtin_ctz(exti_set_mask);
auto &gpio_irq_info = irq_callback_table[index];
Проблема здесь в том, что irq_callback_table — это std::array размера 16. exti_set_mask — это uint16_t, который вероятно, повышается до uint32_t (32-битная архитектура ЦП), поэтому компилятор не может быть уверен, что результат __builtin_ctz() вернет что-то меньшее чем 16. Из-за возможности доступа за пределами границ программный код взрывается из-за всего кода, добавленного для поддержки генерации исключения.
Маскировка результата перед его использованием поскольку индекс избавляется от всего этого кода исключений:
Код: Выделить всё
uint8_t index = __builtin_ctz(exti_set_mask) & 0xf;
auto &gpio_irq_info = irq_callback_table[index];
В результате размер программного кода снова уменьшается примерно до 4 КБ по сравнению с обычным кодом. 90 КБ!
Эти флаги установлены через meson:
Код: Выделить всё
# Specify global compiler flags.
add_project_arguments(
# Free standing environment (no OS, or stdlib)
'-ffreestanding', '-nostdlib', '-specs=nosys.specs',
# Enable linker garbage collection
'-ffunction-sections', '-fdata-sections',
# No dynamic memory allocation
'-fno-builtin-malloc', '-fno-builtin-calloc',
'-fno-builtin-realloc', '-fno-builtin-free',
# Debug optimization
'-Og',
language: ['cpp', 'c']
)
add_project_arguments(
'-std=c++20',
'-fno-exceptions',
'-fno-rtti',
language: ['cpp']
)
Но флага -fno-Exceptions, похоже, недостаточно для предотвращения генерации кода исключения. В идеале я бы хотел, чтобы любая потенциальная эмиссия исключений (или malloc и т. д.) вместо этого отображалась как предупреждение или ошибка. Есть идеи, как этого добиться?
Подробнее здесь:
https://stackoverflow.com/questions/793 ... exceptions