Comments 17
Вынести его в отдельную функцию в глобальной области видимости, а затем ещё придумывать корректное название
понимаю эти чувства но всё же это поиск проблемы там где её нет :) ну придумайте общее правило для конструирования подобных названий и делов-то (имя вызывающей функции и суфикс "sort" и т.п.), функцию объявите как статик и никому не помешает.
ваш подход снижает читабельность (ну она и просто за счет удлиннения внешней функции снижается) - и это перевешивает небольшие потенциальные плюсы, хотя как трюк - занятно
Я б так делать не стал. Это очень не по-сишному, поэтому ваш код контринтуитивен и чтобы его понять, придётся внимательно вчитываться в ваши макросы. На мой взгляд, это перевешивает все достоинства.
я так делал на С++ в своём пазле - он не продакшен только для меня, ну тут смотря чего хотим добиться, если сплетения в коде переплелись и много проверок то проще забиндить и сверху или в другом файле смотреть(возможно не удобно, но проверки разные бывают) ), так а еще интересное заметил, не знаю как в винде под С, но строка может быть утф32(ну или интереснее утф8+емодзи), всё таки аски скучно как бы не звучало это, жаль что этого пока нету по умолчанию в стандарте
Я проще поинтересуюсь - а зачем это вот всё? Я просто эмбеддер и для программирования мк обхожусь без таких вот приёмов. Где вот без этого, ну вот никак? Не сочтите за негатив, мне реально интересно для расширения кругозора.
Все ради того, чтобы писать короткие колбеки. В эмбеде их полно
Так я и буду использовать колбек. Вы уж простите меня за тупость. Вот самый пионерский колбек по кнопке и пину порта:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == GPIO_PIN_13)
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
}
}
Чего тут ещё воротить? Все итак до безобразия просто и понятнее понятного...
Я бы сделал так (давно на Си не писал, не серчайте за ошибки):
// Makes a name unique for a context.
// fn1 is an 'internal' function, fn2 is the context.
#define INTERNAL_FOR(fn1, fn2) fn1##_internal_for_##fn2
bool INTERNAL_FOR(asc, foo1)(int e1, int e2)
{
return e1 < e2;
}
void foo1()
{
…
my_sort(my_array1, INTERNAL_FOR(asc, foo1));
…
}
bool INTERNAL_FOR(asc, foo2)(char* e1, char* e2)
{
return human_order_compare(e1, e2, OMIT_LEADING_FLAG);
}
void foo2()
{
…
my_sort(my_array2, INTERNAL_FOR(asc, foo2));
…
}
Возможно я не ясно выразился, но когда я сказал сложно придумать имя функции, я имел ввиду сложно придумать имя которое описывало бы действие функции. Разумеется к предикату сравнивающего два элемента это не относится, но если там некоторая формула или более сложное условие, будет проще не только не называть ее, но потом при чтении кода не придется искать определение этой функции или гадать какое действие она выполняет.
Так это уже будут анонимные функции (лямбды). А в заголовке — «аналог вложенным». В чём суть вложенности? Не замусоривать глобальный неймспейс и не иметь конфликтов. Что и достигнуто.
Для читабельных лямбд, мне кажется, сишного препроцессинга не хватит.
Классически для этого используются макросы.
с код он такой, какой есть. Это почти всегда простыня с использованием goto. Что либо глобально в нем улучшить почти невозможно. Поэтому смысла отходить от канонов программирования на нем нет.
Вообще то в gcc есть вложенные функции. Ну если не хочется костылить на ucontext и прочими longjump))
Я так понимаю что это что-то вроде continuation написанный вручную через создание структуры хранящей состояние или что-то вроде async/await стейт-машины из одного шага. Интересное теоретическое использование, но на практике это закат солнца вручную, где нужно вручную создавать структуру и переключать стейты, лишь бы не писать вложенные функции.
Аналог вложенным функциям на языке программирования Си