Объявление функции по указателю. Синтаксис
Класика C (gcc):
typedef struct {
const char *cmd; tp_parser_status(*exe)(uint8_t *str);
}tp_uart_tag;
const static char cmd_ask[] = "?";
uint8_t cmd_exe_ask(uint8_t *str)
{
/*********/
return PARSER_OK;
}
tp_uart_tag uart_tags[]={
{.cmd = cmd_ask, .exe = cmd_exe_ask },
{.cmd = NULL, .exe = NULL }
};
Есть ли возможность объявить функцию неявно? Что-то вроде (cmd_exe_ask
в данном примере):
tp_uart_tag uart_tags[]={
{.cmd = cmd_RF_Preamble, .exe = (uint8_t *str){ return PARSER_OK;} },
{.cmd = NULL, .exe = NULL }
};
Ответы (2 шт):
Хороший вопрос, подталкивает поразмышлять... В самом деле, в gcc нет лямбд.
Но если подумать для чего они реально нужны (отбросим желание иметь наиболее краткий код), то довольно очевидно, что они хороши для доступа к значениям локальных переменных функции, в теле которой определяется лямбда.
И тут можно вспомнить, что в gcc существуют nested functions, которые обладают тем же свойством, в них можно обращаться к переменным объемлющей функции.
Тогда можно написать что-то в таком духе (я никоим образом не советую на самом деле программировать в таком стиле, кроме как только лишь для экспериментов с языком)
void
foo (int a)
{
auto tp_parser_status bar(uint8_t *str);
tp_uart_tag uart_tags[]={
{.cmd = cmd_RF_Preamble, .exe = bar },
{.cmd = NULL, .exe = NULL }
};
......
tp_parser_status bar(uint8_t *str) {
return strcmp(str, uart_tags[a].cmd) == 0 ?
PARSER_OK : 0xff;
}
............
}
Ключевое слово auto в forward declaration функции bar()
нужно, поскольку по умолчанию forward declarations функций относятся к обычным статическим, а не nested функциям и без него компилятор будет ругаться на определение bar()
ниже.
В соответствии с этим ответом:
GNU в той или иной мере все-таки имеет поддержку "лямбда фукций". Основное их ограничение: они должны быть объявлены внутри другой фукции. То есть подобный код
int main(void)
{
tp_uart_tag uart_tags[]={
{
.cmd = cmd_ask,
.exe = cmd_exe_ask
},
{
.cmd = NULL,
.exe = ({
uint8_t __fn__ (uint8_t *str) { return 1; }
__fn__;
})
}
};
return 0;
}
GCC компилирует без проблем. Также мы можем вынести массив uart_tags
из main
'а, а его членов объявлять в любой удобной для нас функции, что выглядит очень близко к тому, что вы задумали.