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

(Не)доработки языков программирования

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, увы, не везде можно прямо использовать ((

Особенно, если речь идет про куски кода, критичные к скорости выполнения или чужие куски кода, в который порой лучше и не соваться.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это легко реализовать в run-time, всего один раз запускать проверку на дубликаты значений.

Всё что может делаться в build-time там и должно делаться. Хотя бы потому что эти данные являются аргументами для других вычислений выполняемых также в build-time. Тогда и все их придётся тоже в runtime переносить добавляя кучу лишнего кода, снижая эффективность.

 

Кстати, мне еще никогда не приходилось сталкиваться с таким - механизм, в котором одинаковые значения запрещены, и в чужом коде тоже.

По мне - экзотика :laughing: .

Я выше писал области применения этого.

Я не знаю как Вы свои исходники пишете, но у меня есть общий файл описания ресурсов периферии для проекта, где описываются используемые ноги, каналы DMA, вектора прерывания, номера UART-ов, таймеров и пр. Между ними есть зависимости. И если я меняю скажем UART0 на UART1, то потом нужно вспоминать какие с ним связаны UART-ы или DMA-каналы или вектора прерываний. И кроме того - проверять ещё все остальные на возможные конфликты с ними. Это куча ненужной работы. Которую лучше поручить компилятору.

Это одна из очевидных областей применения. Очень важная.

Или Вы всё пересчитываете вручную и используемые ресурсы записываете числами в исходник? Тогда сочувствую тем, кто будет это сопровождать/модифицировать :laughing:

 

Что-то типа unique_case в SV? Атрибут такой ввести? Ну, пусть. :santa2:

Типа того. Или просто отдельное зарезервированное слово.

 

Наверно, проще будет вообще отказаться от таких "странных" инициализируемых не нулем массивов и переделать их под constexpr структуры с явной инициализацией полей.

Отказаться от константных массивов??? :wacko: А как жить?

И что странного в массивах констант и зачем их инициализировать нулями??? :blink:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Всё что может делаться в build-time там и должно делаться. Хотя бы потому что эти данные являются аргументами для других вычислений выполняемых также в build-time. Тогда и все их придётся тоже в runtime переносить добавляя кучу лишнего кода, снижая эффективность.

Элементы массива будут использоваться в build-time только если массив идет как constexpr. В противном случае от run-time никуда не деться.

С другой стороны проверку числа инициализаторов можно делать в run-time через обычный assert.

В Release сборку такие проверки разумеется никогда не должны попадать. Полагаю, что это подразумевается само собой.

 

 

Но у меня есть общий файл описания ресурсов периферии для проекта, где описываются используемые ноги, каналы DMA, вектора прерывания, номера UART-ов, таймеров и пр. Между ними есть зависимости. И если я меняю скажем UART0 на UART1, то потом нужно вспоминать какие с ним связаны UART-ы или DMA-каналы или вектора прерываний. И кроме того - проверять ещё все остальные на возможные конфликты с ними. Это куча ненужной работы. Которую лучше поручить компилятору.

 

У меня почти все эти зависимости заложены внутри соотв. библиотеки, однажды отлажены и подключаются к проектам в виде библиотеки.

Построение проекта иное - все сложено не в один файл, а разложены по соотв. модулям с целью минимизации связей модулей друг с другом.

Так проще переносить модули из одного проекта в другой. Камень (ядро) значения не имеет. Изменения в коде весьма минимальные и касаются лишь соотв hpp-файла модуля.

 

Отказаться от константных массивов??? :wacko: А как жить?

Я к этому не призывал, а предложил заменить такие массивы на другие сущности.

Это позволяет вообще отказаться от проверки числа инициализаторов. "Проблема" отпадает сама собой, да и код читается проще.

Кстати, приведите какой-нить конкретный пример. Попробуем сообща разобраться, как это лучше "обойти" ;) А то мне на ум, увы, ничего не приходит ((

 

и зачем их инициализировать нулями???
В этом случае я имел ввиду обычные массивы в ОЗУ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Элементы массива будут использоваться в 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 и забывании внесения изменения в один из массивов свойств, он бы не скомпилился, а вылетел по ошибке при компиляции.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как Вы умудрились создать такую универсальную библиотеку,

Не библиотеку, а библиотекИ. Под каждое семейство своя библиотека (lib-файл), но интерфейс практически одинаковый - базовый класс, шаблоны-наследники и т. п. Поэтому легко переносится платфморозависимый код от проекта к проекту.

Учесть все вариации невозможно, поэтому контроль за правильностью подключения тех же каналов DMA возлагается на программера, т.е. на меня. И без даташита, разумеется, никуда.

 

например имеем некий список:...

Эти свойства раскиданы по разным файлам, а enum - в хидере. И очень хочется, чтобы при добавлении элемента в enum и забывании внесения изменения в один из массивов свойств, он бы не скомпилился, а вылетел по ошибке при компиляции.

Если эта конструкция может эволюционировать и ее функционал может в будущем сильно измениться, то я бы весь этот толстый функционал сделал бы на плюсах (классы/шаблоны).

Более конкретное решение в этом случае сильно зависит от того, как это будет использоваться в коде.

 

Как это у вас все используется и как должно размещаться в С и H файлах?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Эти свойства раскиданы по разным файлам, а enum - в хидере. И очень хочется, чтобы при добавлении элемента в enum и забывании внесения изменения в один из массивов свойств, он бы не скомпилился, а вылетел по ошибке при компиляции.

http://www.pixelbeat.org/programming/gcc/static_assert.html

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Учесть все вариации невозможно, поэтому контроль за правильностью подключения тех же каналов DMA возлагается на программера, т.е. на меня.

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

 

Как это у вас все используется и как должно размещаться в С и H файлах?

Я же написал: в хидере прописан список (enum), а в тех местах где для элементов этого списка надо получать какие-то константные значения (свойства), прописаны указанные массивы.

Сейчас пока обхожусь просто: при добавлении/удалении элемента список - поиск по всем исходникам последнего элемента списка OSCSRC_n (последний элемент в таких списках у меня - это количество элементов). А в каждом массиве есть это количество (OSCSRC_n).

Но лучше чтобы такую работы делал компилятор, если вдруг отвлекусь на что-то и не скорректирую количество элементов в одном из массивов - чтобы он пнул меня.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Тут как и везде - главное найти некий компромисс ))

 

Я же написал: в хидере прописан список (enum), а в тех местах где для элементов этого списка надо получать какие-то константные значения (свойства), прописаны указанные массивы.

Я имел ввиду применение конкретно этого примера в конкретном коде (куски кода). Ну да ладно, в целом более-менее понятно.

 

Сейчас пока обхожусь просто: при добавлении/удалении элемента список - поиск по всем исходникам последнего элемента списка OSCSRC_n (последний элемент в таких списках у меня - это количество элементов). А в каждом массиве есть это количество (OSCSRC_n).

Тут уже предложили что-нить готовое из std:: array , map.

Конечно, это не совсем compile-time, но тем не менее ;)

 

Но лучше чтобы такую работы делал компилятор, если вдруг отвлекусь на что-то и не скорректирую количество элементов в одном из массивов - чтобы он пнул меня.

Еще бы!

 

Я наверно в подобном случае применил бы фишки от с++11: constexpr и инициализация полей структур прямо в самих структурах. Заодно это позволить вообще отказаться от этих невнятных "магических" наборов в стиле: { 3, 7, 54 }.

Но также придется каждому полю давать имена и конечный код придется корректировать под все это. Правда, однажды.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Оккам не одобряет.

А мы, русские, говорим "Есть такая простота, которая хуже воровства"

 

Например, "Чем меньше элементов в схеме - тем она надёжней"

За такую простоту и желание "не плодить лишние сущности" УБИВАТЬ надо :maniac:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Аналогично! ;)

Сокращается объем текста кода, его проще читать, да и размер прошивки тоже выходит меньше.

Единственное, в драйверах, которые работают в прерываниях и должны работать максимально быстро, стараюсь использовать эти прелести аккуратно.

 

За такую простоту и желание "не плодить лишние сущности" УБИВАТЬ надо :maniac:

Вы вроде обещали без эмоций, в соседней теме. Хотя, кто вы такой, что решать кого "убивать". Так кто-то может и вас решить кокнуть. Потом не обижайтесь.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Единственное, в драйверах, которые работают в прерываниях и должны работать максимально быстро, стараюсь использовать эти прелести аккуратно.

Подавляющее большинство нововведений новых стандартов не влияют на производительность, а влияют лишь на удобство применения и упрощение/сокращение кода.

Вопросов тут больше к тому или иному компилятору, насколько он хорош в новом стандарте. И на качество стандартных библиотек std, без которых от новых стандартов толку мало.

Да и более свежий компилятор, даже если не использовать фишки новых стандартов, все равно лучше топчет старый код. Хоть немного, но лучше.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подавляющее большинство нововведений новых стандартов не влияют на производительность, а влияют лишь на удобство применения и

Я имел в виду друго. Например контейнеры не использую в прерываниях. Они же могут к malloc (new) обрщаться. А делать выделение памяти не комильфо, например в векторе прерывания. Но здесь есть, конечно, нюансы.

Да и более свежий компилятор, даже если не использовать фишки новых стандартов, все равно лучше топчет старый код. Хоть немного, но лучше.

Надеюсь на это, но нужно проверять, если есть заинтересованность.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я Например контейнеры не использую в прерываниях.

Ну, само собой в прерываниях вообще нельзя ничего подобного использовать.

Минимум действий: сброс аппаратного флажка (если нужно), семафор/флаг/сообщение "наверх" для соотв. задачи и на выход.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но лучше чтобы такую работы делал компилятор, если вдруг отвлекусь на что-то и не скорректирую количество элементов в одном из массивов - чтобы он пнул меня.

 

костыли конечно, но вроде работают

 

#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);

можно ещё дополнить имя енума более осмысленным выводом об ошибке.

ну а если у кого идиосинкразия на макросы, тоже самое можно и шаблонами сделать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

например имеем некий список:

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

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