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

VladislavS

Свой
  • Постов

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

  • Посещение

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

    9

Сообщения, опубликованные VladislavS


  1. 23 минуты назад, Arlleex сказал:

    Ну и опять же, плюсы развиваются куда стремительнее по отношению к Си

    К сожалению, недостаточно быстро. Сами новшества по капле раз в три года, а компиляторы потом ещё догоняют годами. 

     

    23 минуты назад, Arlleex сказал:

    а самое главное, не всегда совместимо между версиями

    А вот это как раз неправда. Стремление к максимальной совместимости со старым кодом (для нас это конечно хорошо) является чуть ли не основным тормозом развития языка.

    23 минуты назад, Arlleex сказал:

    слишком много вариантов описания одного и того же

    Ничего удивительного, ведь у нас язык высокого уровня и мы пишем не инструкции процессора, а алгоритмы работы с данными. Более того, только с volatile данными! Алгоритмы можно по разному написать, это норм.

     

    23 минуты назад, Arlleex сказал:

    постепенно забивает на ембеддед

    Я бы не сказал. В языке всё больше компайлтайм вычислений. Всё больше контейнеров в стандартной библиотеки оптимизируют для работы без динамической памяти. Всё это только приближает к использованию в эмбедде.

    23 минуты назад, Arlleex сказал:

    например, я о составных присваиваниях |= над volatile переменными в C++20

    Это попытка убрать зависимые от компилятора реализации. Да, немного неудобно на старом коде в эмбедде, но мешает не сильно. Можно как переписать, так и подавить предупреждение. Понимание зачем это нужно есть.

     

    23 минуты назад, Arlleex сказал:

    Справедливости ради, NULL не обязательно должен иметь бинарное значение 0

    По хорошему, он вообще не должен иметь значения отображающегося на адресацию памяти. Как определить, вернулся NULL или это реальная память по адресу 0?

    21 минуту назад, Arlleex сказал:

    А Вы ожидали другого? Чего?

    Я ожидал компактного и оптимизированного цикла копирования 32-битными словами. Код с memcpy и memset получается больше и медленнее. Уж поверьте, проверено.

    Неочевидное добавление вот сюда volatile делает код меньше и быстрее.

    for(volatile uint32_t* pSrc = _sidata, *pDst = _sdata; pDst != _edata; *pDst++ = *pSrc++);

     

    21 минуту назад, Arlleex сказал:

    каждые три года надо было только нововведения проработать

    Именно так. Сидишь и как дурак ждешь три года эти нововведения чтобы применять можно было, когда хочется уже сейчас :)))

  2. 1 час назад, dimka76 сказал:

    Это вообще вывих мозга и мартышкин язык

    Функция как функция, просто вы не привыкли что в этом месте её можно написать. А когда самостоятельно напишешь лямбду пару раз, да ещё в том месте где она реально нужна, то всё становится понятно и логично.

  3. 48 минут назад, dxp сказал:

    это низкоуровневая запись,

    Самое прикольное, что это не имеет ничего общего с конечным кодом. Компилятор потом из него делает что хочет. Это просто запись алгоритма, а для его записи очень часто все эти индексы не нужны. Если алгоритм подразумевает "для всех элементов сделать что-то", то логично это так и написать for(auto &x :  data) f(x);

    1 час назад, dimka76 сказал:

    Даже не знающий языка интуитивно сможет понять, что тут происходит

    Это не так. Все эти С-шные шифровки без знания языка невозможно разобрать. Так же и вы С++ код не понимаете, потому что не знаете языка - ничего удивительного. Для тех кто изучал язык (не видел где-то, а изучал) код читается легко и естественно.

    ЗЫ:

    Пример из жизни. В стартапе для копирования секций данных и зануления 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 соответственно.

  4. 57 минут назад, dxp сказал:

    Почему с шаблонными это автоматом получится?

    Согласен, тут некорректно сформулировал. 

    57 минут назад, dxp сказал:

    Что имеется в виду?

    Если речь про обычное программирование, то на С++17 гарантия выполнения код в компайлтайме - использовать значение функции там где должна быть константа. Например, constexpr auto var = f();  , в if constexpr, как параметр шаблона. Иногда вместо consteval действительно приходится промежуточную constexpr "переменную" делать. С другой стороны, при максимальной оптимизации компилятор и так всё это делает. Уговаривать его надо когда нет оптимизации, а у меня такого не бывает.

    Если речь про метапрограммы, то там уход в пространство типов гарантирует. Хотя, последние версии языка как раз упрощают метапрограммы, позволяя писать всё больше в пространстве данных в привычном виде.

    Я сначала обрадовался когда появилась consteval.  Но когда начал применять, то оказалось, что многие функции имеют место быть как в компайлтайме, так и в рантайме и ограничивать их функционал особого смысла нет.

  5. 7 минут назад, dxp сказал:

    consteval для функций

    Его функционал сильно преувеличен. Иногда он даже проблемы создаёт. Не вижу особого смысла ограничивать функции этапом компиляции. Если они шаблонные, то это автоматом получится, а если обычные пусть живут где хотят. Есть другой инструмент не пустить код в рантайм.

  6. 42 минуты назад, dxp сказал:

    constexpr может использоваться в выражениях if для управления условной компиляцией

     

    if constexpr это не условная компиляция в том виде как его С-шники понимают.. В этом месте ожидается/требуется выражение, которое будет вычислени на этапе компиляции. Оно будет скомпилировано по обоим веткам и в обоих случаях будет синтаксически проверено. А при инстанциации в код попадёт только нужная ветка. Причём они могут обе использоваться в зависимости от того как вызвали. В отличии от условной компиляции, где кусок кода просто выкидывается и его ни использовать, ни проверить на корректность нельзя.

     

    42 минуты назад, dxp сказал:

    Наверное, вспомнилось далеко не всё,

    Для эмбедда шаблоны рулят. Многие сущности у нас вариативны и их параметры можно инстанцировать оптимальным способом на этапе компиляции. Шаблоны с переменным количеством параметров позволяют уводить код в пространство типов (фактически метапрограммирование). Компилятор делает очень много за программиста, что ускоряет разработку, избавляет от ошибок и делает оптимизации, которые руками делать лениво и кропотливо - компилятор не устаёт и не ошибается. Всё это уже в С++17 доступно.

     

    Из плюшек С++20 основное, пожалуй, концепты. Они делают библиотеки более надёжными - программист задаёт ограничения на входные данные. Вычищают код от SFINAE - кто знает что это такое поймут насколько проще становится код. Во многих местах можно избавиться от static_assert - опять же код чище получается. Сильно повышается информативностьь сообщений компилятора об ошибках - отлаживать шаблонный код становится проще, уходят километровые непонятные ошибки.

    Ну там шаблонные лямбды с переменным количеством параметров код проще делают. Рэнжи и всё больше контейнеров в constexpr, хотя для эмбедда это не столь применимо. Модули пока чисто теоретически код лучше сделают, выхлопа от них я ещё не видел. Ну и т.д.

  7. 20 часов назад, dxp сказал:

    Многие участники форума, я видел, уже давно и успешно используют возможности C++11 (а может и 14), не испугались нововведений, хотя из-за них код программ местами сильно поменялся. 

    У меня С++17 в продакшене. Работаю с ARM, RISC-V и наследство AVR иногда всплывает. На С++20 делаю наработки на перспективу - код реально проще и надёжнее получается. От полного перехода останавливает только поддержка компиляторами.

  8. 8 часов назад, mantech сказал:

    ради текстовой компактности можно пожертвовать такими потерями в скорости

    Нет никакой  "такой потери скорости". А зачастую есть именно выигрыш в скорости.

  9. Можно. Пример sct

    Спойлер
    #! armclang -E --target=arm-arm-none-eabi -mcpu=cortex-m4 -xc
    
    #define __ROM_BASE     0x08000000
    #define __ROM_SIZE     (1024*128)
    
    #define __RAM_BASE     0x20000000
    #define __RAM_SIZE     (1024*32)
    
    #define __CCMRAM_BASE  0x10000000
    #define __CCMRAM_SIZE  (1024*8)
    
    #define __STACK_SIZE       1024
    #define __HEAP_SIZE        0
    
    #define __STACK_TOP    (__CCMRAM_BASE + __CCMRAM_SIZE) /* Stack starts at end of CCMRAM */
    #define __HEAP_BASE    (AlignExpr(+0, 8))              /* Heap starts after RW_RAM section, 8 byte aligned */
    
    #define __RW_SIZE        (__RAM_SIZE - __STACK_SIZE - __HEAP_SIZE)
    
    LR_FLASH __ROM_BASE __ROM_SIZE       ; load region size_region
    {    
      ER_IROM1 __ROM_BASE __ROM_SIZE     ; load address = execution address
      {  
       *.o (RESET, +First)
       *(InRoot$$Sections)
       .ANY (+RO)
       .ANY (+XO)
      }
    
      RW_IRAM1 __RAM_BASE __RW_SIZE      ; RW data
      {  
       .ANY (+RW +ZI)
      }
    
    #if __HEAP_SIZE > 0
      ARM_LIB_HEAP  __HEAP_BASE EMPTY  __HEAP_SIZE  {}  ; Reserve empty region for heap  
    #endif
    
      ARM_LIB_STACK __STACK_TOP EMPTY -__STACK_SIZE {}  ; Reserve empty region for stack
    }

     

     

  10. На Cortex-M3 таблица векторов вот так переносится

    extern void(*__vector_table[])();
    SCB->VTOR = (uint32_t)&__vector_table;

    Где __vector_table название таблицы векторов из стартапа. В случае применения HAL надо искать по коду SCB->VTOR, так как он может с ним что-то делать.

  11. 7 часов назад, C2000 сказал:

    Как избавится от стандартного sturtup? хочу использовать свой стартап файл прямо в проекте.

    Об IAR для какого процессора речь? Для ARM, например, startup есть в любом проекте в виде исходника. Меняй сколько хочешь.

    В папке с установленным IAR много разной документации. В EWARM_DevelopmentGuide.ENU.pdf много полезного.

  12. 10 минут назад, dimka76 сказал:

    Вы приводили пример для другого компилятора

    Дело даже не в компиляторе. На уровне языка можно только предполагать где что будет размещено. А дальше можно чем-то управлять ключами, чем-то скриптом линкера. Всё  implementation dependent, так вроде в стандарте языка сказано.

    6 минут назад, MKdemiurg сказал:

    Вообще странно, что это компиляторо зависимое поведение

    Ничего странного. Стандарт языка не определяет как оно под капотом должно работать. Что-то в gcc поменяли в очередной версии. Бывает.

    Более того, то что .noinit ведёт себя как обычная непривилегированная секция, в отличии от .bss, очень даже правильно. 

    • Upvote 1
  13. Да пофиг на атрибуты секции rwx. Надо линкеру в скрипте сказать, что эту секцию не загружать. В случае с .bss это автоматом, видимо, происходит - компилятор и линкер знают про неё. Для .noinit кроме названия (линкеру пофиг на него должно быть) ничего не говорит, что её надо игнорить.

    4 минуты назад, jcxz сказал:

    А если написать как в IAR? с __no_init

    Это расширение IAR и только IAR. Для совмесиимости лучше наоборот в iar писать __attribute__.

    4 минуты назад, jcxz сказал:

    Должен быть какой-то атрибут, типа __no_init IAR.

    В коде нет, в скрипте линкера всё.

  14. 3 минуты назад, jcxz сказал:

    020000042000DA

    А вот и он, гнилой зуб. Осталось по map посмотреть что в 2000DA00 попало.

    8 минут назад, jcxz сказал:

    А что с ним не так?

    Там не очевидно, попало ли туда что-то. Эта секция как bss не объявлена.

  15. 5 минут назад, MKdemiurg сказал:

    да в Хекс вроде как норм

    Не хотите же вы сказать, что содержимое bin и hex  отличается? Они должны одни и те же данные описывать. Только в hex по адресам всё видно, а в bin "дыры" место занимают.

×
×
  • Создать...