Перейти к содержанию
    

VladislavS

Свой
  • Постов

    1 241
  • Зарегистрирован

  • Посещение

  • Победитель дней

    9

Весь контент VladislavS


  1. -std=c++98 Впрочем, то что не собирается лучше исправить. Потому что на моей памяти из языка выпиливали только реальные эпик фэйлы. С оптимизирующим компилятором в C/C++ это в принципе невозможно. Скорее это неправда. А говорите от эмбеддеров отвернулись :))) Это в GCC. Естественно с оптимизацией. У меня код без оптимизации не бывает в принципе. Метапрограммирование. Какой бы хитрый он не был, это вызов библиотечной функции вместо тупого цикла на месте.
  2. К сожалению, недостаточно быстро. Сами новшества по капле раз в три года, а компиляторы потом ещё догоняют годами. А вот это как раз неправда. Стремление к максимальной совместимости со старым кодом (для нас это конечно хорошо) является чуть ли не основным тормозом развития языка. Ничего удивительного, ведь у нас язык высокого уровня и мы пишем не инструкции процессора, а алгоритмы работы с данными. Более того, только с volatile данными! Алгоритмы можно по разному написать, это норм. Я бы не сказал. В языке всё больше компайлтайм вычислений. Всё больше контейнеров в стандартной библиотеки оптимизируют для работы без динамической памяти. Всё это только приближает к использованию в эмбедде. Это попытка убрать зависимые от компилятора реализации. Да, немного неудобно на старом коде в эмбедде, но мешает не сильно. Можно как переписать, так и подавить предупреждение. Понимание зачем это нужно есть. По хорошему, он вообще не должен иметь значения отображающегося на адресацию памяти. Как определить, вернулся NULL или это реальная память по адресу 0? Я ожидал компактного и оптимизированного цикла копирования 32-битными словами. Код с memcpy и memset получается больше и медленнее. Уж поверьте, проверено. Неочевидное добавление вот сюда volatile делает код меньше и быстрее. for(volatile uint32_t* pSrc = _sidata, *pDst = _sdata; pDst != _edata; *pDst++ = *pSrc++); Именно так. Сидишь и как дурак ждешь три года эти нововведения чтобы применять можно было, когда хочется уже сейчас :)))
  3. Функция как функция, просто вы не привыкли что в этом месте её можно написать. А когда самостоятельно напишешь лямбду пару раз, да ещё в том месте где она реально нужна, то всё становится понятно и логично.
  4. Самое прикольное, что это не имеет ничего общего с конечным кодом. Компилятор потом из него делает что хочет. Это просто запись алгоритма, а для его записи очень часто все эти индексы не нужны. Если алгоритм подразумевает "для всех элементов сделать что-то", то логично это так и написать for(auto &x : data) f(x); Это не так. Все эти С-шные шифровки без знания языка невозможно разобрать. Так же и вы С++ код не понимаете, потому что не знаете языка - ничего удивительного. Для тех кто изучал язык (не видел где-то, а изучал) код читается легко и естественно. ЗЫ: Пример из жизни. В стартапе для копирования секций данных и зануления bss вот такой код на "ясном и понятном". extern uint32_t _sidata[], _sdata[], _edata[], _sbss[], _ebss[]; for(uint32_t *pSrc=_sidata, *pDst=_sdata; pDst != _edata; *pDst++ = *pSrc++); for(uint32_t *pDst=_sbss; pDst!=_ebss; *pDst++=0); Компилятор покрутил у виска и заменил всё это на memcpy и memset соответственно.
  5. Согласен, тут некорректно сформулировал. Если речь про обычное программирование, то на С++17 гарантия выполнения код в компайлтайме - использовать значение функции там где должна быть константа. Например, constexpr auto var = f(); , в if constexpr, как параметр шаблона. Иногда вместо consteval действительно приходится промежуточную constexpr "переменную" делать. С другой стороны, при максимальной оптимизации компилятор и так всё это делает. Уговаривать его надо когда нет оптимизации, а у меня такого не бывает. Если речь про метапрограммы, то там уход в пространство типов гарантирует. Хотя, последние версии языка как раз упрощают метапрограммы, позволяя писать всё больше в пространстве данных в привычном виде. Я сначала обрадовался когда появилась consteval. Но когда начал применять, то оказалось, что многие функции имеют место быть как в компайлтайме, так и в рантайме и ограничивать их функционал особого смысла нет.
  6. Его функционал сильно преувеличен. Иногда он даже проблемы создаёт. Не вижу особого смысла ограничивать функции этапом компиляции. Если они шаблонные, то это автоматом получится, а если обычные пусть живут где хотят. Есть другой инструмент не пустить код в рантайм.
  7. if constexpr это не условная компиляция в том виде как его С-шники понимают.. В этом месте ожидается/требуется выражение, которое будет вычислени на этапе компиляции. Оно будет скомпилировано по обоим веткам и в обоих случаях будет синтаксически проверено. А при инстанциации в код попадёт только нужная ветка. Причём они могут обе использоваться в зависимости от того как вызвали. В отличии от условной компиляции, где кусок кода просто выкидывается и его ни использовать, ни проверить на корректность нельзя. Для эмбедда шаблоны рулят. Многие сущности у нас вариативны и их параметры можно инстанцировать оптимальным способом на этапе компиляции. Шаблоны с переменным количеством параметров позволяют уводить код в пространство типов (фактически метапрограммирование). Компилятор делает очень много за программиста, что ускоряет разработку, избавляет от ошибок и делает оптимизации, которые руками делать лениво и кропотливо - компилятор не устаёт и не ошибается. Всё это уже в С++17 доступно. Из плюшек С++20 основное, пожалуй, концепты. Они делают библиотеки более надёжными - программист задаёт ограничения на входные данные. Вычищают код от SFINAE - кто знает что это такое поймут насколько проще становится код. Во многих местах можно избавиться от static_assert - опять же код чище получается. Сильно повышается информативностьь сообщений компилятора об ошибках - отлаживать шаблонный код становится проще, уходят километровые непонятные ошибки. Ну там шаблонные лямбды с переменным количеством параметров код проще делают. Рэнжи и всё больше контейнеров в constexpr, хотя для эмбедда это не столь применимо. Модули пока чисто теоретически код лучше сделают, выхлопа от них я ещё не видел. Ну и т.д.
  8. У меня С++17 в продакшене. Работаю с ARM, RISC-V и наследство AVR иногда всплывает. На С++20 делаю наработки на перспективу - код реально проще и надёжнее получается. От полного перехода останавливает только поддержка компиляторами.
  9. Из опыта. Более совершенный инструмент позволяет писать более эффективный код.
  10. Нет никакой "такой потери скорости". А зачастую есть именно выигрыш в скорости.
  11. Макросы зло, их вообще писать не надо. Форматирование чужого кода (библиотек) зло, нечего в него вообще лезть. Как автор написал так и компилировать.
  12. https://developer.arm.com/documentation/dui0474/m/accessing-and-managing-symbols-with-armlink/section-related-symbols/image-symbols Вот так к адресу стека в стратапе получаю доступ #define __STACK_TOP (void *)&Image$$ARM_LIB_STACK$$ZI$$Limit extern int Image$$ARM_LIB_STACK$$ZI$$Limit;
  13. На Cortex-M3 таблица векторов вот так переносится extern void(*__vector_table[])(); SCB->VTOR = (uint32_t)&__vector_table; Где __vector_table название таблицы векторов из стартапа. В случае применения HAL надо искать по коду SCB->VTOR, так как он может с ним что-то делать.
  14. Все средства разработки отлично в Windows работают без танцев с бубном. Просто берёшь и работаешь. К чему всё это? 😮
  15. Об IAR для какого процессора речь? Для ARM, например, startup есть в любом проекте в виде исходника. Меняй сколько хочешь. В папке с установленным IAR много разной документации. В EWARM_DevelopmentGuide.ENU.pdf много полезного.
  16. А что даташит про это говорит?
  17. Дело даже не в компиляторе. На уровне языка можно только предполагать где что будет размещено. А дальше можно чем-то управлять ключами, чем-то скриптом линкера. Всё implementation dependent, так вроде в стандарте языка сказано. Ничего странного. Стандарт языка не определяет как оно под капотом должно работать. Что-то в gcc поменяли в очередной версии. Бывает. Более того, то что .noinit ведёт себя как обычная непривилегированная секция, в отличии от .bss, очень даже правильно.
  18. Перемещение и выкидывание это разные вещи. Компилятор может rom->ram по разным критериям перекидывать. Ради скорости, например.
  19. Да пофиг на атрибуты секции rwx. Надо линкеру в скрипте сказать, что эту секцию не загружать. В случае с .bss это автоматом, видимо, происходит - компилятор и линкер знают про неё. Для .noinit кроме названия (линкеру пофиг на него должно быть) ничего не говорит, что её надо игнорить. Это расширение IAR и только IAR. Для совмесиимости лучше наоборот в iar писать __attribute__. В коде нет, в скрипте линкера всё.
  20. А вот и он, гнилой зуб. Осталось по map посмотреть что в 2000DA00 попало. Там не очевидно, попало ли туда что-то. Эта секция как bss не объявлена.
×
×
  • Создать...