-
Постов
1 240 -
Зарегистрирован
-
Посещение
-
Победитель дней
9
Сообщения, опубликованные VladislavS
-
-
1 час назад, dimka76 сказал:
Это вообще вывих мозга и мартышкин язык
Функция как функция, просто вы не привыкли что в этом месте её можно написать. А когда самостоятельно напишешь лямбду пару раз, да ещё в том месте где она реально нужна, то всё становится понятно и логично.
-
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 соответственно.
-
57 минут назад, dxp сказал:
Почему с шаблонными это автоматом получится?
Согласен, тут некорректно сформулировал.
57 минут назад, dxp сказал:Что имеется в виду?
Если речь про обычное программирование, то на С++17 гарантия выполнения код в компайлтайме - использовать значение функции там где должна быть константа. Например, constexpr auto var = f(); , в if constexpr, как параметр шаблона. Иногда вместо consteval действительно приходится промежуточную constexpr "переменную" делать. С другой стороны, при максимальной оптимизации компилятор и так всё это делает. Уговаривать его надо когда нет оптимизации, а у меня такого не бывает.
Если речь про метапрограммы, то там уход в пространство типов гарантирует. Хотя, последние версии языка как раз упрощают метапрограммы, позволяя писать всё больше в пространстве данных в привычном виде.
Я сначала обрадовался когда появилась consteval. Но когда начал применять, то оказалось, что многие функции имеют место быть как в компайлтайме, так и в рантайме и ограничивать их функционал особого смысла нет.
-
7 минут назад, dxp сказал:
consteval для функций
Его функционал сильно преувеличен. Иногда он даже проблемы создаёт. Не вижу особого смысла ограничивать функции этапом компиляции. Если они шаблонные, то это автоматом получится, а если обычные пусть живут где хотят. Есть другой инструмент не пустить код в рантайм.
-
42 минуты назад, dxp сказал:
constexpr может использоваться в выражениях if для управления условной компиляцией
if constexpr это не условная компиляция в том виде как его С-шники понимают.. В этом месте ожидается/требуется выражение, которое будет вычислени на этапе компиляции. Оно будет скомпилировано по обоим веткам и в обоих случаях будет синтаксически проверено. А при инстанциации в код попадёт только нужная ветка. Причём они могут обе использоваться в зависимости от того как вызвали. В отличии от условной компиляции, где кусок кода просто выкидывается и его ни использовать, ни проверить на корректность нельзя.
42 минуты назад, dxp сказал:Наверное, вспомнилось далеко не всё,
Для эмбедда шаблоны рулят. Многие сущности у нас вариативны и их параметры можно инстанцировать оптимальным способом на этапе компиляции. Шаблоны с переменным количеством параметров позволяют уводить код в пространство типов (фактически метапрограммирование). Компилятор делает очень много за программиста, что ускоряет разработку, избавляет от ошибок и делает оптимизации, которые руками делать лениво и кропотливо - компилятор не устаёт и не ошибается. Всё это уже в С++17 доступно.
Из плюшек С++20 основное, пожалуй, концепты. Они делают библиотеки более надёжными - программист задаёт ограничения на входные данные. Вычищают код от SFINAE - кто знает что это такое поймут насколько проще становится код. Во многих местах можно избавиться от static_assert - опять же код чище получается. Сильно повышается информативностьь сообщений компилятора об ошибках - отлаживать шаблонный код становится проще, уходят километровые непонятные ошибки.
Ну там шаблонные лямбды с переменным количеством параметров код проще делают. Рэнжи и всё больше контейнеров в constexpr, хотя для эмбедда это не столь применимо. Модули пока чисто теоретически код лучше сделают, выхлопа от них я ещё не видел. Ну и т.д.
-
20 часов назад, dxp сказал:
Многие участники форума, я видел, уже давно и успешно используют возможности C++11 (а может и 14), не испугались нововведений, хотя из-за них код программ местами сильно поменялся.
У меня С++17 в продакшене. Работаю с ARM, RISC-V и наследство AVR иногда всплывает. На С++20 делаю наработки на перспективу - код реально проще и надёжнее получается. От полного перехода останавливает только поддержка компиляторами.
-
Из опыта. Более совершенный инструмент позволяет писать более эффективный код.
-
С++ vs C, конечно же. Питон то тут каким боком?
-
8 часов назад, mantech сказал:
ради текстовой компактности можно пожертвовать такими потерями в скорости
Нет никакой "такой потери скорости". А зачастую есть именно выигрыш в скорости.
-
1 час назад, sasamy сказал:
Я даже не знаю где он нужен кроме игроделия.
В embedded.
-
Макросы зло, их вообще писать не надо.
Форматирование чужого кода (библиотек) зло, нечего в него вообще лезть. Как автор написал так и компилировать.
-
В 22.12.2023 в 17:03, dmitrykhom сказал:
Это чересчур - у меня прерывание раз в 10 мкс, мне так нельзя.
Прерыванию выше приоритет поставить?
-
1 минуту назад, mantech сказал:
Мне одному показалось, что она вручную спаяна
Да ещё и скальпелем поработали...
-
Можно. Пример 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 }
-
Вот так к адресу стека в стратапе получаю доступ
#define __STACK_TOP (void *)&Image$$ARM_LIB_STACK$$ZI$$Limit extern int Image$$ARM_LIB_STACK$$ZI$$Limit;
-
На Cortex-M3 таблица векторов вот так переносится
extern void(*__vector_table[])(); SCB->VTOR = (uint32_t)&__vector_table;
Где __vector_table название таблицы векторов из стартапа. В случае применения HAL надо искать по коду SCB->VTOR, так как он может с ним что-то делать.
-
Все средства разработки отлично в Windows работают без танцев с бубном. Просто берёшь и работаешь. К чему всё это? 😮
-
7 часов назад, C2000 сказал:
Как избавится от стандартного sturtup? хочу использовать свой стартап файл прямо в проекте.
Об IAR для какого процессора речь? Для ARM, например, startup есть в любом проекте в виде исходника. Меняй сколько хочешь.
В папке с установленным IAR много разной документации. В EWARM_DevelopmentGuide.ENU.pdf много полезного.
-
-
10 минут назад, dimka76 сказал:
Вы приводили пример для другого компилятора
Дело даже не в компиляторе. На уровне языка можно только предполагать где что будет размещено. А дальше можно чем-то управлять ключами, чем-то скриптом линкера. Всё implementation dependent, так вроде в стандарте языка сказано.
6 минут назад, MKdemiurg сказал:Вообще странно, что это компиляторо зависимое поведение
Ничего странного. Стандарт языка не определяет как оно под капотом должно работать. Что-то в gcc поменяли в очередной версии. Бывает.
Более того, то что .noinit ведёт себя как обычная непривилегированная секция, в отличии от .bss, очень даже правильно.
-
1
-
-
Перемещение и выкидывание это разные вещи. Компилятор может rom->ram по разным критериям перекидывать. Ради скорости, например.
-
Да пофиг на атрибуты секции rwx. Надо линкеру в скрипте сказать, что эту секцию не загружать. В случае с .bss это автоматом, видимо, происходит - компилятор и линкер знают про неё. Для .noinit кроме названия (линкеру пофиг на него должно быть) ничего не говорит, что её надо игнорить.
4 минуты назад, jcxz сказал:А если написать как в IAR? с __no_init
Это расширение IAR и только IAR. Для совмесиимости лучше наоборот в iar писать __attribute__.
4 минуты назад, jcxz сказал:Должен быть какой-то атрибут, типа __no_init IAR.
В коде нет, в скрипте линкера всё.
-
3 минуты назад, jcxz сказал:
020000042000DA
А вот и он, гнилой зуб. Осталось по map посмотреть что в 2000DA00 попало.
8 минут назад, jcxz сказал:А что с ним не так?
Там не очевидно, попало ли туда что-то. Эта секция как bss не объявлена.
-
5 минут назад, MKdemiurg сказал:
да в Хекс вроде как норм
Не хотите же вы сказать, что содержимое bin и hex отличается? Они должны одни и те же данные описывать. Только в hex по адресам всё видно, а в bin "дыры" место занимают.
Стили оформления программ на C/C++ и их применимость
в Cредства разработки для МК
Опубликовано · Пожаловаться
К сожалению, недостаточно быстро. Сами новшества по капле раз в три года, а компиляторы потом ещё догоняют годами.
А вот это как раз неправда. Стремление к максимальной совместимости со старым кодом (для нас это конечно хорошо) является чуть ли не основным тормозом развития языка.
Ничего удивительного, ведь у нас язык высокого уровня и мы пишем не инструкции процессора, а алгоритмы работы с данными. Более того, только с volatile данными! Алгоритмы можно по разному написать, это норм.
Я бы не сказал. В языке всё больше компайлтайм вычислений. Всё больше контейнеров в стандартной библиотеки оптимизируют для работы без динамической памяти. Всё это только приближает к использованию в эмбедде.
Это попытка убрать зависимые от компилятора реализации. Да, немного неудобно на старом коде в эмбедде, но мешает не сильно. Можно как переписать, так и подавить предупреждение. Понимание зачем это нужно есть.
По хорошему, он вообще не должен иметь значения отображающегося на адресацию памяти. Как определить, вернулся NULL или это реальная память по адресу 0?
Я ожидал компактного и оптимизированного цикла копирования 32-битными словами. Код с memcpy и memset получается больше и медленнее. Уж поверьте, проверено.
Неочевидное добавление вот сюда volatile делает код меньше и быстрее.
for(volatile uint32_t* pSrc = _sidata, *pDst = _sdata; pDst != _edata; *pDst++ = *pSrc++);
Именно так. Сидишь и как дурак ждешь три года эти нововведения чтобы применять можно было, когда хочется уже сейчас :)))