Объявление функции по указателю. Синтаксис

Класика 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 шт):

Автор решения: avp

Хороший вопрос, подталкивает поразмышлять... В самом деле, в 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() ниже.

→ Ссылка
Автор решения: Max I

В соответствии с этим ответом:

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'а, а его членов объявлять в любой удобной для нас функции, что выглядит очень близко к тому, что вы задумали.

→ Ссылка