In addition to @Some programmer dude
answer:
Instead of writing function's name twice you can use preprocessor (stringify):
#define FUNC_MAP_ENTRY(name) { #name, &name}
const struct name_function_map_struct name_function_map[] = {
FUNC_MAP_ENTRY(foo1),
FUNC_MAP_ENTRY(foo2),
FUNC_MAP_ENTRY(foo3)
};
By the way,
if you use C++ or you have some dynamic array in pure C (it's not hard to implement) you could make dynamic table this is working example how to implement dynamic function table:
// MIT license
// Copyright 2017 "Yet Another John Smith"
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
// associated documentation files (the "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial
// portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
// EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
// THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
// ================================
// Dynamic function names table
// ================================
struct FuncNamesTableEntry
{
const char* name;
// You could make it more flexibile (could store any function type)
// say use (void*), but user have to cast it by hand then
void(*func_ptr)(void);
};
struct FuncNamesTable
{
struct FuncNamesTableEntry* entries;
size_t size;
size_t capacity;
};
void func_table_init(struct FuncNamesTable * tbl)
{
tbl->entries = NULL;
tbl->size = 0;
tbl->capacity = 0;
}
#define eprintf(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
void func_table_add_entry(
struct FuncNamesTable * tbl,
struct FuncNamesTableEntry entry)
{
if (tbl->size >= tbl->capacity) {
struct FuncNamesTableEntry* new_mem;
size_t new_capacity = tbl->capacity * 1.5 + 1;
new_mem = realloc(tbl->entries, new_capacity * sizeof(struct FuncNamesTableEntry));
if (new_mem == NULL) {
printf("%s\n", "Not enough memory");
exit(1);
}
tbl->entries = new_mem;
tbl->capacity = new_capacity;
}
tbl->entries[tbl->size] = entry;
tbl->size += 1;
}
struct FuncNamesTable _the_func_table;
// I need this hack to make ADD macro
struct FuncNamesTableEntry _insterting_entry;
#define FUNC_TABLE_INIT() func_table_init(&_the_func_table);
//#define FUNC_TABLE_ENTRY(f_name) struct FuncNamesTableEntry{#f_name, &f_name}
#define FUNC_TABLE_ADD_ENTRY(f_name) do{ \
_insterting_entry.name = #f_name; \
_insterting_entry.func_ptr = &f_name; \
func_table_add_entry(&_the_func_table, _insterting_entry); \
}while(0);
#define FUNC_TABLE_ITERATE(_i) \
for (struct FuncNamesTableEntry* _i = _the_func_table.entries; \
_i - _the_func_table.entries < _the_func_table.size; \
++_i)
void foo1(void){}
void foo2(void){}
void foo3(void){}
void foo4(void){}
void foo5(void){}
void foo6(void){}
int main(int argc, char const *argv[])
{
FUNC_TABLE_INIT();
FUNC_TABLE_ADD_ENTRY(foo1);
FUNC_TABLE_ADD_ENTRY(foo2);
FUNC_TABLE_ADD_ENTRY(foo3);
FUNC_TABLE_ADD_ENTRY(foo4);
if (1) {
FUNC_TABLE_ADD_ENTRY(foo5);
}
else {
FUNC_TABLE_ADD_ENTRY(foo6);
}
FUNC_TABLE_ITERATE(i)
{
printf("Name: '%s'; pointer: %p\n", i->name, i->func_ptr);
}
return 0;
}