[uquote="VladislavS",url="/forum/viewtopic.php?p=3707495#p3707495"]На самом деле и 25 байтам неоткуда взяться.[/uquote]
У тебя вроде стартап другой, в стандартном стартапе объявлены 6 extern переменных, а сами они в скрипте линкера определены, видимо потому компилятор их выкинуть не может... Но эти 24+1 байт будут и в проекте на С, так что безусловно С++ тут не при чем. Наверное если бы у мк не было 48КБ RAM, то полез бы разбираться, на AVR точно бы полез
[uquote="ARV",url="/forum/viewtopic.php?p=3707507#p3707507"]то, что вы в main написали 3 строчки не делает ваш проект простым - за кадром остались простыни шаблонов и куча подключаемых файлов. то есть при отладке вы будете видеть не три эти строчки, а какие-то загадочные наборы символов из шаблона, разобраться в которых сможет лишь академик программистских наук. ну и мне это зачем? мне ковыряться в сложной иерархии шаблонных классов, которые на самом деле заменены парой ассемблерных команд (и понять, почему - отдельная тема) совсем не улыбается...[/uquote]
Очередные страшилки

Компиляторы умнеют, в язык добавляются новые возможности, в том числе и призванные избавиться от громоздких и непонятных ошибок при работе с шаблонами, библиотеки переписываются с учетом этих нововведений и т.д.... Последний раз мне попадалась такая действительно размашистая ошибка несколько лет назад на ПК, на мк такого не помню вообще, хотя безусловно если не знать С++, то и с теми ошибками что есть разобраться будет очень сложно. Товарищ при помощи моих либ делает кормушку для животных, причем там есть кнопки, пульт, Esp8266, Sim800, чтоб можно было с дома передавать команды на дачу

Естественно шаговик, чтоб крутить заслонку, RTC, эмуляции EEPROM во флеше мк, дисплей 176*220, у меня такого не было, но взглянув на документацию переделал файл для одного из своих дисплеев, отправил его товарищу и, не без везения, но заработало с первого раза, он даже менюшку сам пытался писать и даже можно сказать как-то работало, но потом мне надоело смотреть на мучения и написал универсальную

Так вот у него это все работает при этом даже С он знает на достаточно низком уровне, но либы построенны таким образом, что максимально все проверяют во время компиляции, а если включены ассерты, то и во время выполнения. Например, если вернуться к SPI:
Using - это тот же typedef, т.е. тут объявляется новый тип, это не реально исполняемый код, но при компиляции там много чего выполняется и проверяется. У ног SPI есть ремап на разные пины и для каждого еще нужно задавать номер альтернативной функции, но тут это делается автоматически и конкретно для этого кода получим ошибку компиляции конкретно говорящую о том, что MISO задан неверно, на PB5 ее сремапить нельзя. Если ошибки нет, значит все ноги из списка допустимых и был добавлен правильный номер AF. Или если попытаться нарисовать часть линии за пределами экрана, добавить данные в заполненный RingBuffer и т.д., то получим сообщение об ошибке в консоль красным цветом. Это все помогает обнаруживать большое количество ошибок, а ошибки компилятора мне товарищ иногда шлет, но чего-то большого связанного с шаблонами пока не было
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3707549#p3707549"]Вы лукавите. Покажите ассемблерный код. Я только в этой строке вижу намного больше 4 байт расхода стека.[/uquote]
Чего вдруг компилятор должен показывать статистику по стеку? Он там вообще динамический, да и какая разница сколько на него ушло, если в С уйдет столько же? Один статический методы класса вызывается другие, к ним привязаны только константы, экземпляр класса не создается - это то же самое, что убрать класс и запихнуть функции в namespace, а он просто область видимости ограничивает, так что никаких отличий от просто сишных функций не будет.
И что Вы потом будете делать при отладке? Результат работы препроцессора хотя бы можно увидеть, а это? Если мне не хватает CPP, я использую Perl. Но тогда все промежуточные результаты я вижу и контролирую.
Возьмем класс для работы с портами, т.к. с точки зрения метапрограммирования он самый сложный. Если сделать что-то совсем простое:
то автоматически будет вызвана constexpr функция transformToPins() которая берет все входные параметры, а это могут быть не только пины, но и другие списки и еще парочка других сущностей, и преобразует их только в пины, попутно проверяя нет ли там дубликатов. Результат присваивается constexpr полю класса существующему только во время компиляции, потому брейкоинты ставить бесполезно. Но если параллельно создать такую-же функцию transformToPins2(), убрать constexpr, добавить _noinline_ и присвоить результат обычной переменной, то все замечательно отлаживается:
Спойлер

На скрине видно, что из входного списка pins один пин уже удалился и добавился в outs, правда видно это по типам списков, сами они пустые, но какая разница, если это позволяет нормально все отлаживать
