-
- Реализация очень сильно зависит от архитектуры и возможностей контроллера прерываний. VVB(3555 знак., 06.10.2022 10:26)
- Просто вызываю из прерывания любую функцию любого класса. Зачем ещё
что-то выдумывать? - Ale3000(06.10.2022 08:34)
- Так об этом и вопрос - как оформить(привязать) вызов любой функции
из прерывания. Пока, как я понял, делается массово в стиле С, но
никто не мешает пробовать и по другому. - symbions(06.10.2022 09:32)
- Очень просто оформляется: Ale3000(213 знак., 06.10.2022 11:01)
- Для того чтобы вызвать прерывание нужен адрес. Как его сказать контроллеру (в таблицу прерываний или напрямую в контроллер прерываний) зависит от архитектуры железки. А вот где взять этот адрес уже от языка зависит. И если адрес С-ной функции взять труда не составляет, то указетель на метод класса/объекта в С++ это нетривиальная, зависящая от реализации компилятором сущность. Поэтому, оборачиваем С-функцией и не парим себе мозги. - VladislavS.(06.10.2022 10:57)
- Так об этом и вопрос - как оформить(привязать) вызов любой функции
из прерывания. Пока, как я понял, делается массово в стиле С, но
никто не мешает пробовать и по другому. - symbions(06.10.2022 09:32)
- Если бы разработчики С++ захотели, они бы, вероятно, легко сделали
это. Tyмблep(1006 знак., 03.10.2022 13:08)
- Ага, разработчики тех же кортексов сделали вход в прерывание за 12
тактов как раз для того чтобы мы с this успевали промудохаться. :) - VladislavS.(03.10.2022 13:23)
- Это бесконечный старый спор. Tyмблep(248 знак., 03.10.2022 14:07)
- Ну так и решать пикосекундные задачи тоже - VladislavS.(03.10.2022 14:20)
- Да, если понадобиться, тогда ASM. Tyмблep(244 знак., 03.10.2022 14:24)
- В мелких контроллерах, типа кортексов или AVR таблица векторов
прерываний это константные данный этапа компиляции. То есть,
компилятор должен знать адрес на момент линковки. Всякие
динамически создаваемые объекты плохо тут ложатся. Получается, либо
установка векторов в рантайме с переносом таблицы векторов в RAM
(если такая возможность есть). Либо прослойка просто через таблицу
в RAM (если возможности перенести таблицу нет). В обоих случаях
накладные расходы. VladislavS.(144 знак., 03.10.2022 14:35)
- Это проблема поддержки со стороны разработчиков компилятора. Tyмблep(3046 знак., 03.10.2022 16:28)
- Вот, функции для работы с потоками Виндус - обратите внимание на lpParameter : Tyмблep(545 знак., 03.10.2022 16:42)
- По идее constexpr bind( F&& f,
Args&&... args ); у которого определены все аргументы
должен давать тип void(*)(void) и его наверное можно запихнуть в
таблицу векторов, но нужно изучать, проверять и потом бояцца, как
бэ в очередной версии компилятора не поломалось. - =AlexD=(03.10.2022 15:09)
- Мне думается, в constexpr какой-нибудь каст точно не пройдёт. - VladislavS.(03.10.2022 16:07)
- Это проблема поддержки со стороны разработчиков компилятора. Tyмблep(3046 знак., 03.10.2022 16:28)
- В мелких контроллерах, типа кортексов или AVR таблица векторов
прерываний это константные данный этапа компиляции. То есть,
компилятор должен знать адрес на момент линковки. Всякие
динамически создаваемые объекты плохо тут ложатся. Получается, либо
установка векторов в рантайме с переносом таблицы векторов в RAM
(если такая возможность есть). Либо прослойка просто через таблицу
в RAM (если возможности перенести таблицу нет). В обоих случаях
накладные расходы. VladislavS.(144 знак., 03.10.2022 14:35)
- Да, если понадобиться, тогда ASM. Tyмблep(244 знак., 03.10.2022 14:24)
- Ну так и решать пикосекундные задачи тоже - VladislavS.(03.10.2022 14:20)
- Это бесконечный старый спор. Tyмблep(248 знак., 03.10.2022 14:07)
- Ага, разработчики тех же кортексов сделали вход в прерывание за 12
тактов как раз для того чтобы мы с this успевали промудохаться. :) - VladislavS.(03.10.2022 13:23)
- никак. Nikolay801_(733 знак., 03.10.2022 10:51)
- Не-не-не, что-то не то. Вот в plain C есть обработчик, функция void my_isr(void); - что в этом случае у плюсов? Класс? Функция? Может ли extern "C" void my_isr(void) {} внутри себя вызывать методы классов? Если буфер реализован
классом, как из обработчика положить в него данные? Как проверить
состояние пина, если порт-пин описан сущностями Ц++, через те же
темплейты, например? - Dingo(03.10.2022 09:57)
- По аналогии у плюсов Tyмблep(30 знак., 03.10.2022 13:11)
- А что остановит использовать темплейт? Вот пример. Тут PE8 это
шаблонный тип и LED это шаблонный тип. Или ниже пример с USB - куда
уж шаблонней? VladislavS.(306 знак., 03.10.2022 10:19 - 10:30, картинка)
- Спасибо. Я помню ваш пример с Key (
но уже вряд ли найдунашел!-> ). Dingo(1 знак., 03.10.2022 10:50, ссылка)
- Спасибо. Я помню ваш пример с Key (
- Кстати, в жизни всё гораздо проще. Обработчк прерывания - обычная
функция, в которой делается ровно то что она должна делать. Надо
флаг в регистре сбросить - сбрасываем флаг с помощью CMSIS. Надо
светодиодом мигнуть - дёргаем метод класса светодиода. Без всяких
комплексов. - VladislavS.(03.10.2022 09:15)
- Очень легкомысленное заявление. Во всей ветке обсуждения я не
увидел ни слова про реентерабельность функций для прерываний. Costic(700 знак., 03.10.2022 16:45)
- Потому что реентерабельность это совсем из другой оперы. Какая
разница называете вы функции методами, а данные членами или нет?
Какая разница будут shared данные глобальными или членами класса?
Ничего же не меняется от этого. Членов хоть от несанкционированного
доступа защитить можно. - VladislavS.(03.10.2022 16:58)
- Опера всё та же. Когда в классе функции-члены вызываются из разных
мест и могут прерываться, то важно чтобы они были реентерабельными. - Costic(03.10.2022 18:55)
- А когда функции не члены, не важно что ли? Зачем на этом акцент сделан? - VladislavS.(03.10.2022 19:32)
- Опера всё та же. Когда в классе функции-члены вызываются из разных
мест и могут прерываться, то важно чтобы они были реентерабельными. - Costic(03.10.2022 18:55)
- Потому что реентерабельность это совсем из другой оперы. Какая
разница называете вы функции методами, а данные членами или нет?
Какая разница будут shared данные глобальными или членами класса?
Ничего же не меняется от этого. Членов хоть от несанкционированного
доступа защитить можно. - VladislavS.(03.10.2022 16:58)
- ... надо символ в очередь внутри класса положить - кладём - =AlexD=(03.10.2022 09:37)
- А format c: /q можно? :) - VladislavS.(03.10.2022 09:46)
- "Можно. Но потом. Весь накопитель в труху". Пардон, не удержался. - Dingo(03.10.2022 09:58)
- А format c: /q можно? :) - VladislavS.(03.10.2022 09:46)
- Очень легкомысленное заявление. Во всей ветке обсуждения я не
увидел ни слова про реентерабельность функций для прерываний. Costic(700 знак., 03.10.2022 16:45)
- Самое простое - обычные функции в плюсах никто не запрещал. Чуть
посложнее методы классов делать обработчиками, но и это возможно, с
опытом придёт. - VladislavS.(03.10.2022 07:07)
- Любопытно, вот есть класс UART, в нем обработчик прерывания void
i();. В программе создаем два объекта UART u1, u2; Как привязать
u1.i() и u2.i() к разным физическим прерываниям, не используя
Сишных прокладок? - AlexBi(03.10.2022 08:22)
- Никак. Т.к. ядро процессора/контроллера не умеет одновременно указатель на объект (this) и адрес/смещение функции вычислить. - Costic(03.10.2022 16:50)
- Как вариант. Переносите таблицу прерываний в ОЗУ. В конструктор класса UART передаёте его номер и создаёте объекты UART u1(1), u2(2); Конструктор класса UART устанавливает свой обработчкик в таблицу векторов прерываний при создании объекта. Можно и другие варианты придумать, была бы необходимость. Но прокладка - самое простое. Мир от её использования не перевернётся. - VladislavS.(03.10.2022 10:06)
- Так элементарно. Обработчик прерывания - обычная Си'шная функция
extern "C" { void Uart1Int(void) { u1.i(); } void Uart2Int(void) {
u2.i(); } } - =AlexD=(03.10.2022 08:28)
- Это и есть сишные прокладки, нет? КМК, значительная часть проблем
плюсов в том, что плюсовая публика излишне идеологизирована: "Нет
сишным прокладкам! Мы тут плюсы или где?" - SciFi(03.10.2022 08:35)
- Это ваши тараканы какие-то. Почему вы боитесь "прокладок"? Они даже
накладных расходов не несут. Смотрите примеры: VladislavS.(1068 знак., 03.10.2022 08:54)
- static не годится, т.к. для u1 и u2 он будет одинаковый. Сишные
прокладки не удобны, т.к. u1 может быть внутри другого объекта, а
тот внутри еще чего-то, либо вообще создаваться динамически. Вся
красота теряется. - AlexBi(03.10.2022 09:12)
- Бесконечное вложение классов дуг в друга - это не "красиво" - =AlexD=(03.10.2022 09:38)
- Не класса в класс, а объекта в объект или объекта в класс. - VladislavS.(03.10.2022 09:43)
- Чуть ниже пример с USB. Там обработчик статик, но вызвает методы разных объектов в зависимости от того какой из портов обрабатывает. - VladislavS.(03.10.2022 09:32)
- Задачи бывают разные. Где-то static подойдёт, где-то метод динамически созданного объекта (в эмбедде? правда, правда?). - VladislavS.(03.10.2022 09:17)
- Бесконечное вложение классов дуг в друга - это не "красиво" - =AlexD=(03.10.2022 09:38)
- Это прекрасно. Только непонятно, зачем вообще нужен класс, когда
там всего две функции. Лишняя сущность же. - SciFi(03.10.2022 08:56)
- Или вот пример обработчиков с шаблонным классом. В контроллере два
USB, класс один, объектов два, обработчиков прерываний два. VladislavS.(1 знак., 03.10.2022 09:33, картинка)
- А я бы привёл другой пример. Да, с лишним сгенерённым кодом, но
может быть он понятнее "бедуинам"? Costic(541 знак., 03.10.2022 17:09, ссылка)
- Зачем же в микроконтроллере объекты динамически создавать? VladislavS.(1 знак., 03.10.2022 17:37, ссылка)
- В моём примере демонстрировались виртуальные функции. Подправил так: Costic(1 знак., 03.10.2022 18:49, ссылка)
- Зачем же в микроконтроллере объекты динамически создавать? VladislavS.(1 знак., 03.10.2022 17:37, ссылка)
- вот, похоже на ответ. То есть из plain C можно обращаться уже к C++
выходит? - Dingo(03.10.2022 10:09)
- Без некоторого рукоблудства нет. В С++ есть механизм перегрузки
функций. Чтобы компилятор различал разные кандидаты на перегрузку
при компиляции к именам функций добавляются префиксы, зависящие от
аргументов. В объектных файлах эти имена могут быть очень
причудливыми. Например, SysTick_Handler() превратится в
_Z15SysTick_Handlerv. Если функции с аргументами, то имя сильно
разрастается. Функцию с таким именем из С-кода не вызвать. Для того
чтобы отключить этот механизм VladislavS.(160 знак., 03.10.2022 10:28 - 10:41)
- Это позволяет из ASM, и любого другого языка вызвать С++ функцию,
если он поддерживает Си'шное соглашение о вызовах. - =AlexD=(03.10.2022 10:31)
- В общем случае именно так. - VladislavS.(03.10.2022 10:33)
- Это позволяет из ASM, и любого другого языка вызвать С++ функцию,
если он поддерживает Си'шное соглашение о вызовах. - =AlexD=(03.10.2022 10:31)
- Это С++, просто указание компилятору, что вот к этому конкретному имени функции применяется asm трансляция имён в стиле Си, а не С++. - =AlexD=(03.10.2022 10:24)
- Без некоторого рукоблудства нет. В С++ есть механизм перегрузки
функций. Чтобы компилятор различал разные кандидаты на перегрузку
при компиляции к именам функций добавляются префиксы, зависящие от
аргументов. В объектных файлах эти имена могут быть очень
причудливыми. Например, SysTick_Handler() превратится в
_Z15SysTick_Handlerv. Если функции с аргументами, то имя сильно
разрастается. Функцию с таким именем из С-кода не вызвать. Для того
чтобы отключить этот механизм VladislavS.(160 знак., 03.10.2022 10:28 - 10:41)
- Кто-нибудь рискнёт сказать, что тут прокладки и это "недостаточно
С++"? Для реализации подобного на С две почти одинаковые функции
придётся писать? Только не надо про макросы... - VladislavS.(03.10.2022 09:52)
- Почему же не надо про макросы? Шаблоны это грубо замена макросам.
Предложенный пример спокойно реализуется через склейку. Только вся
натянутость шаблонных решений (плевать шаблоны плюсов или макросы)
не помогает навигации/отладке. Не буду говорить плохо о плюсах, а
хорошо не могу - у меня на них идиосинкразия. НО пример,
КМК,подобран именно идеологический и выбран вариант получения
экземпляров метода в зависимости от параметра с прицелом на
не-рантайм. В Сях не-рантайм - это Vit(263 знак., 03.10.2022 11:33)
- Макросы не имеют области видимости. Вот в виндузовых хедерах
какой-то альтернативно одарённый перец догадался определить макросы
min и max ловеркейсом, и привет - вы пишете void set_limits(int
min, int max), и препроцессор вам вместо параметров функции
подставляет самизнаетечто. С шаблонами такого не происходит. - йцyкeн(03.10.2022 13:19)
- Криворукость и возможности:) - это всегда расширяет кругозор:))) Я,
например, отношусь к шаблонам как к костылям, которые лишь
позволили говорить, что "можно без макросов". Для меня они ещё
более отдаляют С++ от удобоваримости Vit(1 знак., 03.10.2022 13:55, картинка)
- Просто вы не умеете их готовить. Для меня китайский - сущая
тарабарщина, а 1.5 млрд китайцев на нём говорят и не парятся. - VladislavS.(03.10.2022 14:49)
- Так и не собираюсь. Хотя иногда приходится копаться в. Считаю плюсы
рудиментарным звеном:) между Си и Си-Шарпом - Vit(03.10.2022 16:06)
- C# в микроконтроллер? Оригинально. Ж) - VladislavS.(03.10.2022 16:45)
- Так и не собираюсь. Хотя иногда приходится копаться в. Считаю плюсы
рудиментарным звеном:) между Си и Си-Шарпом - Vit(03.10.2022 16:06)
- Просто вы не умеете их готовить. Для меня китайский - сущая
тарабарщина, а 1.5 млрд китайцев на нём говорят и не парятся. - VladislavS.(03.10.2022 14:49)
- Криворукость и возможности:) - это всегда расширяет кругозор:))) Я,
например, отношусь к шаблонам как к костылям, которые лишь
позволили говорить, что "можно без макросов". Для меня они ещё
более отдаляют С++ от удобоваримости Vit(1 знак., 03.10.2022 13:55, картинка)
- Само собой, пример подобран. Какой смысл показывать примеры, где не будет разницы? В целом вы правильно понимаете суть происходящего, но сильно недооцениваете силу шаблонов и constexpr. - VladislavS.(03.10.2022 11:48)
- Макросы не имеют области видимости. Вот в виндузовых хедерах
какой-то альтернативно одарённый перец догадался определить макросы
min и max ловеркейсом, и привет - вы пишете void set_limits(int
min, int max), и препроцессор вам вместо параметров функции
подставляет самизнаетечто. С шаблонами такого не происходит. - йцyкeн(03.10.2022 13:19)
- На С писать придется примерно так же, как на С++, те же две
функции, или одну, напичканную if-ами. Или я чего-то не понимаю ... AlexBi(1 знак., 03.10.2022 10:29, картинка)
- if будет выполняться в рантайме при каждом вызове прерывания. От if
constexpr останется только USB_FS_OBJECT.Enumerate_Reset() в
прерывании USB_FS, и USB_HS_OBJECT.Enumerate_Reset() в прерывании
USB_HS на этапе компиляции. Никаких if в рантайме не будет. - VladislavS.(03.10.2022 10:42)
- От обычного if, применённого к константе, в коде тоже ничего не
остаётся. йцyкeн(1 знак., 03.10.2022 13:55, ссылка)
- А ещё c простым if обе ветки условия должны корректно компилироваться. С if constexpr они должны быть всего лишь синтаксически правильно составлены. Накидал пример: Под if константа. VladislavS.(8 знак., 03.10.2022 16:11, ссылка)
- Зависит от оптимизации и от того находится ли код в другой единице
трансляции. VladislavS.(8 знак., 03.10.2022 14:23, ссылка)
- Ну разумеется. Вы сделали x не параметром шаблона, а параметром
функции. Теперь это не константа. - йцyкeн(03.10.2022 14:32)
- Как же не константа? Включите -O1 и "о чудо" случится. Самая
настоящая константа. VladislavS.(214 знак., 03.10.2022 14:45)
- Нет. Для функции plusminus x не является константой, поэтому в
ассемблерном тексте проверка условия сохранилась в виде инструкции
cmove. А вот в местах вызова фактические параметры являются
константами, и там оптимизатор заменил вызовы plusminus
результатами этих вызовов. - йцyкeн(03.10.2022 14:47)
- Вот мы и вышли на разный уровень - либо это константа по стандарту языка, либо оптимизатор так решил. Поэтому, где рассчитываем иметь константу пишем if constexpr, чтобы муха не проскочила. Не всегда так просто определить "на глаз" константность данных, пусть этим компилятор занимается. - VladislavS.(03.10.2022 14:53)
- Нет. Для функции plusminus x не является константой, поэтому в
ассемблерном тексте проверка условия сохранилась в виде инструкции
cmove. А вот в местах вызова фактические параметры являются
константами, и там оптимизатор заменил вызовы plusminus
результатами этих вызовов. - йцyкeн(03.10.2022 14:47)
- Как же не константа? Включите -O1 и "о чудо" случится. Самая
настоящая константа. VladislavS.(214 знак., 03.10.2022 14:45)
- Ну разумеется. Вы сделали x не параметром шаблона, а параметром
функции. Теперь это не константа. - йцyкeн(03.10.2022 14:32)
- Чем это будет отличаться от вызова
Enumerate_Reset(&USB_FS_OBJECT) и
Enumerate_Reset(&USB_HS_OBJECT) в соответствующих обработчиках
прерываний, если все писать в С-стиле? - AlexBi(03.10.2022 10:46)
- Тем что метод Enumerate_Reset должен уметь с этим
&USB_FS_OBJECT что-то делать. Это дополнительный код. А выбор
между вызовом Enumerate_Reset(&USB_FS_OBJECT) или
Enumerate_Reset(&USB_HS_OBJECT) в рантайме или макросом? - VladislavS.(03.10.2022 10:54)
- Разве внутри USB_FS_OBJECT.Enumerate_Reset() не делается что-то с
USB_FS_OBJECT? Или смущает что вместо x придется писать
arg->x, или вместо foo() придется писать arg->foo(arg)? AlexBi(237 знак., 03.10.2022 11:13, картинка)
- C++ программиста вообще ничего не смущает, а уж объём текста и
подавно :) А вот во что это в кончном счёте скомпилируется очень
даже. Во-первых, передать аргумент в Enumerate_Reset не бесплатно.
Во-вторых внутри придётся много проверок аргумента делать, чтобы
выбирать с каким из двух USB-портов оперировать. В-третьих,
Enumerate_Reset static inline и его вызова вообще не будет. Что-то
оптимизатор вытянет, но далеко не всё. Код будет медленней, а это
прерывание. Ну и VladislavS.(45 знак., 03.10.2022 11:29)
- Если так переживать за скорость, что учитывать количество
передаваемых аргументов, то в С++ придется делать изрядное
количество static, т.к. любой вызов не static метода неявно требует
передачи одного параметра, а в программах очень часто встречается
единственный объект класса. Не уверен, что оптимизатор способен
обнаружить это самостоятельно и сделать код как для static, хотя
формально препятствий нет. AlexBi(261 знак., 03.10.2022 11:43)
- inline IRQHandler улыбнуло. А куда его можно встроить? Впрочем,
inline это такое слово-паразит в С. Пиши не пиши - ничего не
изменится. В С++ у него хоть другие применения есть. - VladislavS.(03.10.2022 12:27)
- Встраивать я предполагал туда AlexBi(244 знак., 03.10.2022 12:39, картинка)
- Мне кажется, польза inline незаслуженно преувеличена. Он не нужен.
Сэкономить пару тактов? Это бывает нужно два раза в год, и inline
там будет нужен в последнюю очередь. Следовательно, если погромиздъ
применяет inline чаще, чем 2 раза в год, он демонстрирует
неадекватную оценку реальных требований к софту. - SciFi(03.10.2022 12:45)
- На мелких контроллерах типа ПИК это экономия стека, который весьма
мелкий. Но программу при этом удобнее писать в виде отдельных
функций, вызывающих друг друга. Приходится следить за глубиной
вложенности. AlexBi(115 знак., 03.10.2022 12:49)
- Так большинство аргументов обычно и разбивается об скалу "и это всё
ради пары тактов?". А пара тактов тут, пара тактов там, тем более
что это всё делает компилятор и уже набегает разница. - VladislavS.(03.10.2022 12:59)
- Всё так. Только на самом деле не набегает :-) - SciFi(03.10.2022 13:02)
- Есть опыт или с потолка? - VladislavS.(03.10.2022 13:09)
- Опыт есть. И да, "набегает" - это с потолка :-) - SciFi(03.10.2022 13:37)
- Получается моё кун-фу сильнее твоего :) VladislavS.(48 знак., 03.10.2022 13:55, youtube)
- Опыт есть. И да, "набегает" - это с потолка :-) - SciFi(03.10.2022 13:37)
- Есть опыт или с потолка? - VladislavS.(03.10.2022 13:09)
- Всё так. Только на самом деле не набегает :-) - SciFi(03.10.2022 13:02)
- Так большинство аргументов обычно и разбивается об скалу "и это всё
ради пары тактов?". А пара тактов тут, пара тактов там, тем более
что это всё делает компилятор и уже набегает разница. - VladislavS.(03.10.2022 12:59)
- На мелких контроллерах типа ПИК это экономия стека, который весьма
мелкий. Но программу при этом удобнее писать в виде отдельных
функций, вызывающих друг друга. Приходится следить за глубиной
вложенности. AlexBi(115 знак., 03.10.2022 12:49)
- Мне кажется, польза inline незаслуженно преувеличена. Он не нужен.
Сэкономить пару тактов? Это бывает нужно два раза в год, и inline
там будет нужен в последнюю очередь. Следовательно, если погромиздъ
применяет inline чаще, чем 2 раза в год, он демонстрирует
неадекватную оценку реальных требований к софту. - SciFi(03.10.2022 12:45)
- Встраивать я предполагал туда AlexBi(244 знак., 03.10.2022 12:39, картинка)
- В случае с С++ есть возможность писать код методов в заголовочном
файле. Тогда весь код будет в одной единице трансляции и
возможности оптимизации сильно выше. Статик или не статик тогда на
оптимизацию не сильно влияет. Пример на эту тему: VladislavS.(248 знак., 03.10.2022 12:18, картинка)
- Даже если весь код под рукой, компилятор отказывается инлайнить
единственный вызов функции. Правда это все С-компиляторы, с
которыми я имел дело, как у С++ не знаю. - AlexBi(03.10.2022 12:44)
- Да дадно, а если попросить? :) VladislavS.(1 знак., 03.10.2022 13:08, картинка)
- Даже если весь код под рукой, компилятор отказывается инлайнить
единственный вызов функции. Правда это все С-компиляторы, с
которыми я имел дело, как у С++ не знаю. - AlexBi(03.10.2022 12:44)
- Мне тоже кажется жутко неудобным, что нельзя весь класс объявить статическим, не по области видимости, а по методам. - =AlexD=(03.10.2022 11:49)
- inline IRQHandler улыбнуло. А куда его можно встроить? Впрочем,
inline это такое слово-паразит в С. Пиши не пиши - ничего не
изменится. В С++ у него хоть другие применения есть. - VladislavS.(03.10.2022 12:27)
- Если так переживать за скорость, что учитывать количество
передаваемых аргументов, то в С++ придется делать изрядное
количество static, т.к. любой вызов не static метода неявно требует
передачи одного параметра, а в программах очень часто встречается
единственный объект класса. Не уверен, что оптимизатор способен
обнаружить это самостоятельно и сделать код как для static, хотя
формально препятствий нет. AlexBi(261 знак., 03.10.2022 11:43)
- C++ программиста вообще ничего не смущает, а уж объём текста и
подавно :) А вот во что это в кончном счёте скомпилируется очень
даже. Во-первых, передать аргумент в Enumerate_Reset не бесплатно.
Во-вторых внутри придётся много проверок аргумента делать, чтобы
выбирать с каким из двух USB-портов оперировать. В-третьих,
Enumerate_Reset static inline и его вызова вообще не будет. Что-то
оптимизатор вытянет, но далеко не всё. Код будет медленней, а это
прерывание. Ну и VladislavS.(45 знак., 03.10.2022 11:29)
- Разве внутри USB_FS_OBJECT.Enumerate_Reset() не делается что-то с
USB_FS_OBJECT? Или смущает что вместо x придется писать
arg->x, или вместо foo() придется писать arg->foo(arg)? AlexBi(237 знак., 03.10.2022 11:13, картинка)
- Тем что метод Enumerate_Reset должен уметь с этим
&USB_FS_OBJECT что-то делать. Это дополнительный код. А выбор
между вызовом Enumerate_Reset(&USB_FS_OBJECT) или
Enumerate_Reset(&USB_HS_OBJECT) в рантайме или макросом? - VladislavS.(03.10.2022 10:54)
- От обычного if, применённого к константе, в коде тоже ничего не
остаётся. йцyкeн(1 знак., 03.10.2022 13:55, ссылка)
- if будет выполняться в рантайме при каждом вызове прерывания. От if
constexpr останется только USB_FS_OBJECT.Enumerate_Reset() в
прерывании USB_FS, и USB_HS_OBJECT.Enumerate_Reset() в прерывании
USB_HS на этапе компиляции. Никаких if в рантайме не будет. - VladislavS.(03.10.2022 10:42)
- Почему же не надо про макросы? Шаблоны это грубо замена макросам.
Предложенный пример спокойно реализуется через склейку. Только вся
натянутость шаблонных решений (плевать шаблоны плюсов или макросы)
не помогает навигации/отладке. Не буду говорить плохо о плюсах, а
хорошо не могу - у меня на них идиосинкразия. НО пример,
КМК,подобран именно идеологический и выбран вариант получения
экземпляров метода в зависимости от параметра с прицелом на
не-рантайм. В Сях не-рантайм - это Vit(263 знак., 03.10.2022 11:33)
- А я бы привёл другой пример. Да, с лишним сгенерённым кодом, но
может быть он понятнее "бедуинам"? Costic(541 знак., 03.10.2022 17:09, ссылка)
- Чтобы не писать в каждой функции аргументом указатель на структуру с данными. Экономия пальцекликов ;-) Но вообще то прикольно, когда интеллектуальный помощник редактора сам вываливает тебе список методов после точки. Можно не морщить моск и не заглядывать в хедер. Удобненько. - =AlexD=(03.10.2022 09:03)
- Что значит две функции? Это же пример. Класс может быть сколь угодно сложным. Один из методов - обработчик прерываний. Вот вам класс с тремя навороченными методами, один из которых обработчик прерываний. VladislavS.(155 знак., 03.10.2022 09:00)
- Или вот пример обработчиков с шаблонным классом. В контроллере два
USB, класс один, объектов два, обработчиков прерываний два. VladislavS.(1 знак., 03.10.2022 09:33, картинка)
- static не годится, т.к. для u1 и u2 он будет одинаковый. Сишные
прокладки не удобны, т.к. u1 может быть внутри другого объекта, а
тот внутри еще чего-то, либо вообще создаваться динамически. Вся
красота теряется. - AlexBi(03.10.2022 09:12)
- Плюсы в отличии от Си не универсальны, увы. Это совершенно очевидно любому, кто с ними хоть немного поработал. И отсутствие стандарта (хотя бы _дефакто) на именование функций в ASM выхлопе - одна из проблем. Можно извернуться, забиндить метод с аргументом и как-то прописать указатель в таблицу векторов, но это по сути будет ровно то-же самое, что я написал, только через жопу. - =AlexD=(03.10.2022 08:45)
- Это ваши тараканы какие-то. Почему вы боитесь "прокладок"? Они даже
накладных расходов не несут. Смотрите примеры: VladislavS.(1068 знак., 03.10.2022 08:54)
- Это и есть сишные прокладки, нет? КМК, значительная часть проблем
плюсов в том, что плюсовая публика излишне идеологизирована: "Нет
сишным прокладкам! Мы тут плюсы или где?" - SciFi(03.10.2022 08:35)
- Любопытно, вот есть класс UART, в нем обработчик прерывания void
i();. В программе создаем два объекта UART u1, u2; Как привязать
u1.i() и u2.i() к разным физическим прерываниям, не используя
Сишных прокладок? - AlexBi(03.10.2022 08:22)