Forger 17 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба IAR ARM начиная с версии 8 поддерживает как 11 так и 14. ARM со своими компиляторами (встроены в Keil и DS-5) тоже держит 14. 11 - полностью держит только v6, а v5 - почти все, кроме "мелочей," которые скорее всего мало кто использует. 14 - ни кто из них де не поддерживает полностью (( 17 - не пришло время, рано еще )) Да и разница между 11 и 14 заметна не любому глазу. Я бы сказал больше - не многие заметят разницу между C++03 и C++11 ;) Посмотрите в сторону std::array. С ним можно делать все тоже самое. Знаю, но в силу гораздо бОльшей абстракции std::array, увы, не везде можно прямо использовать (( Особенно, если речь идет про куски кода, критичные к скорости выполнения или чужие куски кода, в который порой лучше и не соваться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба Это легко реализовать в run-time, всего один раз запускать проверку на дубликаты значений. Всё что может делаться в build-time там и должно делаться. Хотя бы потому что эти данные являются аргументами для других вычислений выполняемых также в build-time. Тогда и все их придётся тоже в runtime переносить добавляя кучу лишнего кода, снижая эффективность. Кстати, мне еще никогда не приходилось сталкиваться с таким - механизм, в котором одинаковые значения запрещены, и в чужом коде тоже. По мне - экзотика :laughing: . Я выше писал области применения этого. Я не знаю как Вы свои исходники пишете, но у меня есть общий файл описания ресурсов периферии для проекта, где описываются используемые ноги, каналы DMA, вектора прерывания, номера UART-ов, таймеров и пр. Между ними есть зависимости. И если я меняю скажем UART0 на UART1, то потом нужно вспоминать какие с ним связаны UART-ы или DMA-каналы или вектора прерываний. И кроме того - проверять ещё все остальные на возможные конфликты с ними. Это куча ненужной работы. Которую лучше поручить компилятору. Это одна из очевидных областей применения. Очень важная. Или Вы всё пересчитываете вручную и используемые ресурсы записываете числами в исходник? Тогда сочувствую тем, кто будет это сопровождать/модифицировать :laughing: Что-то типа unique_case в SV? Атрибут такой ввести? Ну, пусть. :santa2: Типа того. Или просто отдельное зарезервированное слово. Наверно, проще будет вообще отказаться от таких "странных" инициализируемых не нулем массивов и переделать их под constexpr структуры с явной инициализацией полей. Отказаться от константных массивов??? :wacko: А как жить? И что странного в массивах констант и зачем их инициализировать нулями??? :blink: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба Всё что может делаться в build-time там и должно делаться. Хотя бы потому что эти данные являются аргументами для других вычислений выполняемых также в build-time. Тогда и все их придётся тоже в runtime переносить добавляя кучу лишнего кода, снижая эффективность. Элементы массива будут использоваться в build-time только если массив идет как constexpr. В противном случае от run-time никуда не деться. С другой стороны проверку числа инициализаторов можно делать в run-time через обычный assert. В Release сборку такие проверки разумеется никогда не должны попадать. Полагаю, что это подразумевается само собой. Но у меня есть общий файл описания ресурсов периферии для проекта, где описываются используемые ноги, каналы DMA, вектора прерывания, номера UART-ов, таймеров и пр. Между ними есть зависимости. И если я меняю скажем UART0 на UART1, то потом нужно вспоминать какие с ним связаны UART-ы или DMA-каналы или вектора прерываний. И кроме того - проверять ещё все остальные на возможные конфликты с ними. Это куча ненужной работы. Которую лучше поручить компилятору. У меня почти все эти зависимости заложены внутри соотв. библиотеки, однажды отлажены и подключаются к проектам в виде библиотеки. Построение проекта иное - все сложено не в один файл, а разложены по соотв. модулям с целью минимизации связей модулей друг с другом. Так проще переносить модули из одного проекта в другой. Камень (ядро) значения не имеет. Изменения в коде весьма минимальные и касаются лишь соотв hpp-файла модуля. Отказаться от константных массивов??? :wacko: А как жить? Я к этому не призывал, а предложил заменить такие массивы на другие сущности. Это позволяет вообще отказаться от проверки числа инициализаторов. "Проблема" отпадает сама собой, да и код читается проще. Кстати, приведите какой-нить конкретный пример. Попробуем сообща разобраться, как это лучше "обойти" ;) А то мне на ум, увы, ничего не приходит (( и зачем их инициализировать нулями???В этом случае я имел ввиду обычные массивы в ОЗУ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба Элементы массива будут использоваться в build-time только если массив идет как constexpr. В противном случае от run-time никуда не деться. Какого массива? Вы вообще о чём??? Хотя-бы смотрите на что отвечаете. Отвечаете на вот это сообщение: https://electronix.ru/forum/index.php?showt...t&p=1562937 причём тут какие-то массивы? У меня почти все эти зависимости заложены внутри соотв. библиотеки, однажды отлажены и подключаются к проектам в виде библиотеки. Построение проекта иное - все сложено не в один файл, а разложены по соотв. модулям с целью минимизации связей модулей друг с другом. Так проще переносить модули из одного проекта в другой. Камень (ядро) значения не имеет. Вы кому эти сказки рассказываете? Здесь форум не домохозяек вроде как. Как Вы умудрились создать такую универсальную библиотеку, которая и на STM32 знает какие каналы DMA к какой периферии подключены и какие вектора прерываний и на какие ноги какая периферия выходит. И эта же либа и на LPC и на Tiva и на Infenion и на куче других МК? И всё она одна сама всё определяет? Она видимо и про новые ещё только выходящие МК уже всё знает что и с чем связано и "давно отлажена"... :biggrin: Видимо она сразу даташиты сама читает и куда что надо туда и подключает. Супер-мега либа! :biggrin: :biggrin: :biggrin: Кстати, приведите какой-нить конкретный пример. Попробуем сообща разобраться, как это лучше "обойти" ;) А то мне на ум, увы, ничего не приходит (( например имеем некий список: enum { OSCSRC_ADC_IU, OSCSRC_ADC_IV, OSCSRC_ADC_IW, OSCSRC_ADC_POWER, OSCSRC_RATE, OSCSRC_n}; последнее значение - кол-во элементов списка значений OSCSRC_... Для каждого из элемента есть свойство 1: static u8 const oscsrcSize[OSCSRC_n] = {2, 2, 2, 2, 10}; А также есть свойство 2: static char const oscsrcName[OSCSRC_n * 5 + 1] = "Iu\0\0\0" "Iv\0\0\0" "Iw\0\0\0" "Uz\0\0\0" "Rate\0"; А также есть свойство 3: struct { u8 typ; u8 index; } static u32 const oscsrcFormat[OSCSRC_n] = {{1, 0}, {1, 0}, {1, 0}, {2, 0}, {3, 2}}; Эти свойства раскиданы по разным файлам, а enum - в хидере. И очень хочется, чтобы при добавлении элемента в enum и забывании внесения изменения в один из массивов свойств, он бы не скомпилился, а вылетел по ошибке при компиляции. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба Как Вы умудрились создать такую универсальную библиотеку, Не библиотеку, а библиотекИ. Под каждое семейство своя библиотека (lib-файл), но интерфейс практически одинаковый - базовый класс, шаблоны-наследники и т. п. Поэтому легко переносится платфморозависимый код от проекта к проекту. Учесть все вариации невозможно, поэтому контроль за правильностью подключения тех же каналов DMA возлагается на программера, т.е. на меня. И без даташита, разумеется, никуда. например имеем некий список:... Эти свойства раскиданы по разным файлам, а enum - в хидере. И очень хочется, чтобы при добавлении элемента в enum и забывании внесения изменения в один из массивов свойств, он бы не скомпилился, а вылетел по ошибке при компиляции. Если эта конструкция может эволюционировать и ее функционал может в будущем сильно измениться, то я бы весь этот толстый функционал сделал бы на плюсах (классы/шаблоны). Более конкретное решение в этом случае сильно зависит от того, как это будет использоваться в коде. Как это у вас все используется и как должно размещаться в С и H файлах? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 52 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба Эти свойства раскиданы по разным файлам, а enum - в хидере. И очень хочется, чтобы при добавлении элемента в enum и забывании внесения изменения в один из массивов свойств, он бы не скомпилился, а вылетел по ошибке при компиляции. http://www.pixelbeat.org/programming/gcc/static_assert.html Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба Учесть все вариации невозможно, поэтому контроль за правильностью подключения тех же каналов DMA возлагается на программера, т.е. на меня. А программёру свойственно ошибаться, ибо человек. Вот для этого это и нужно - чтобы возложить всю рутинную работу на компилятор. Как это у вас все используется и как должно размещаться в С и H файлах? Я же написал: в хидере прописан список (enum), а в тех местах где для элементов этого списка надо получать какие-то константные значения (свойства), прописаны указанные массивы. Сейчас пока обхожусь просто: при добавлении/удалении элемента список - поиск по всем исходникам последнего элемента списка OSCSRC_n (последний элемент в таких списках у меня - это количество элементов). А в каждом массиве есть это количество (OSCSRC_n). Но лучше чтобы такую работы делал компилятор, если вдруг отвлекусь на что-то и не скорректирую количество элементов в одном из массивов - чтобы он пнул меня. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба А программёру свойственно ошибаться, ибо человек. Вот для этого это и нужно - чтобы возложить всю рутинную работу на компилятор. Это у меня в планах, но пока обхожусь без этого. Ошибок пока что не было. Наверно, дело в том, что уже научился быстро находить ошибки и приучил так себя писать код, что потом было несложно искать в нем ошибки. Тут как и везде - главное найти некий компромисс )) Я же написал: в хидере прописан список (enum), а в тех местах где для элементов этого списка надо получать какие-то константные значения (свойства), прописаны указанные массивы. Я имел ввиду применение конкретно этого примера в конкретном коде (куски кода). Ну да ладно, в целом более-менее понятно. Сейчас пока обхожусь просто: при добавлении/удалении элемента список - поиск по всем исходникам последнего элемента списка OSCSRC_n (последний элемент в таких списках у меня - это количество элементов). А в каждом массиве есть это количество (OSCSRC_n). Тут уже предложили что-нить готовое из std:: array , map. Конечно, это не совсем compile-time, но тем не менее ;) Но лучше чтобы такую работы делал компилятор, если вдруг отвлекусь на что-то и не скорректирую количество элементов в одном из массивов - чтобы он пнул меня. Еще бы! Я наверно в подобном случае применил бы фишки от с++11: constexpr и инициализация полей структур прямо в самих структурах. Заодно это позволить вообще отказаться от этих невнятных "магических" наборов в стиле: { 3, 7, 54 }. Но также придется каждому полю давать имена и конечный код придется корректировать под все это. Правда, однажды. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Моисей Самуилович 0 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба Оккам не одобряет. А мы, русские, говорим "Есть такая простота, которая хуже воровства" Например, "Чем меньше элементов в схеме - тем она надёжней" За такую простоту и желание "не плодить лишние сущности" УБИВАТЬ надо :maniac: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 23 мая, 2018 Опубликовано 23 мая, 2018 · Жалоба Аналогично! ;) Сокращается объем текста кода, его проще читать, да и размер прошивки тоже выходит меньше. Единственное, в драйверах, которые работают в прерываниях и должны работать максимально быстро, стараюсь использовать эти прелести аккуратно. За такую простоту и желание "не плодить лишние сущности" УБИВАТЬ надо :maniac: Вы вроде обещали без эмоций, в соседней теме. Хотя, кто вы такой, что решать кого "убивать". Так кто-то может и вас решить кокнуть. Потом не обижайтесь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 23 мая, 2018 Опубликовано 23 мая, 2018 · Жалоба Единственное, в драйверах, которые работают в прерываниях и должны работать максимально быстро, стараюсь использовать эти прелести аккуратно. Подавляющее большинство нововведений новых стандартов не влияют на производительность, а влияют лишь на удобство применения и упрощение/сокращение кода. Вопросов тут больше к тому или иному компилятору, насколько он хорош в новом стандарте. И на качество стандартных библиотек std, без которых от новых стандартов толку мало. Да и более свежий компилятор, даже если не использовать фишки новых стандартов, все равно лучше топчет старый код. Хоть немного, но лучше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 23 мая, 2018 Опубликовано 23 мая, 2018 · Жалоба Подавляющее большинство нововведений новых стандартов не влияют на производительность, а влияют лишь на удобство применения и Я имел в виду друго. Например контейнеры не использую в прерываниях. Они же могут к malloc (new) обрщаться. А делать выделение памяти не комильфо, например в векторе прерывания. Но здесь есть, конечно, нюансы. Да и более свежий компилятор, даже если не использовать фишки новых стандартов, все равно лучше топчет старый код. Хоть немного, но лучше. Надеюсь на это, но нужно проверять, если есть заинтересованность. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 23 мая, 2018 Опубликовано 23 мая, 2018 · Жалоба Я Например контейнеры не использую в прерываниях. Ну, само собой в прерываниях вообще нельзя ничего подобного использовать. Минимум действий: сброс аппаратного флажка (если нужно), семафор/флаг/сообщение "наверх" для соотв. задачи и на выход. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 52 23 мая, 2018 Опубликовано 23 мая, 2018 · Жалоба Но лучше чтобы такую работы делал компилятор, если вдруг отвлекусь на что-то и не скорректирую количество элементов в одном из массивов - чтобы он пнул меня. костыли конечно, но вроде работают #define ASSERT_CONCAT_(a, b) a##b #define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b) #define STATIC_ASSERT(e) enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(int)(!!(e)) } enum {OSCSRC_ADC_IU, OSCSRC_ADC_IV, OSCSRC_ADC_IW, OSCSRC_ADC_POWER, OSCSRC_RATE, OSCSRC_n}; static uint8_t const oscsrcSize[] = {2, 2, 2, 2}; //error: enumerator value for 'assert_line_15' is not an integer constant| static uint8_t const oscsrcSize[] = {2, 2, 2, 2, 10}; //ok STATIC_ASSERT(sizeof(oscsrcSize) / sizeof(oscsrcSize[0]) == OSCSRC_n); можно ещё дополнить имя енума более осмысленным выводом об ошибке. ну а если у кого идиосинкразия на макросы, тоже самое можно и шаблонами сделать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 23 мая, 2018 Опубликовано 23 мая, 2018 · Жалоба например имеем некий список: enum { OSCSRC_ADC_IU, OSCSRC_ADC_IV, OSCSRC_ADC_IW, OSCSRC_ADC_POWER, OSCSRC_RATE, OSCSRC_n}; последнее значение - кол-во элементов списка значений OSCSRC_... Для каждого из элемента есть свойство 1: static u8 const oscsrcSize[OSCSRC_n] = {2, 2, 2, 2, 10}; А также есть свойство 2: static char const oscsrcName[OSCSRC_n * 5 + 1] = "Iu\0\0\0" "Iv\0\0\0" "Iw\0\0\0" "Uz\0\0\0" "Rate\0"; А также есть свойство 3: struct { u8 typ; u8 index; } static u32 const oscsrcFormat[OSCSRC_n] = {{1, 0}, {1, 0}, {1, 0}, {2, 0}, {3, 2}}; Эти свойства раскиданы по разным файлам, а enum - в хидере. И очень хочется, чтобы при добавлении элемента в enum и забывании внесения изменения в один из массивов свойств, он бы не скомпилился, а вылетел по ошибке при компиляции. Это как бы делается по другому: // Header file #define ADC_IU OSC_ITEM(ADC_IU, 2, "Iu\0\0\0", 1, 0) #define ADC_IV OSC_ITEM(ADC_IV, 2, "Iv\0\0\0", 1, 0) #define ADC_IW OSC_ITEM(ADC_IW, 2, "Iw\0\0\0", 1, 0) ... #define RATE OSC_ITEM(RATE, 10, "Rate\0", 3, 2) #define OSC_ALL \ ADC_IU OSC_DLM \ ADC_IV OSC_DLM \ ADC_IW OSC_DLM \ ... RATE // In code #define OSC_ITEM(id, _1, _2, _3, _4) OSCSRC_##id #define OSC_DLM , enum { OSC_ALL , OSCSRC_n }; #undef OSC_ITEM ... #define OSC_ITEM(_1, val, _2, _3, _4) val static u8 const oscsrcSize[OSCSRC_n] = { OSC_ALL }; #undef OSC_ITEM ... // etc Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться