Я бы заголовок с функцией ЬурейеЕ и прототипы:
//the_header.h
typedef int intfunc_t(int); /*function not function pointer*/
intfunc_t a,b,c; /*prototypes*/
включить его в каждом файле реализации, а затем один файл с:
#include "the_header.h"
const intfunc_t *func_ptrs[] = { a,b,c };
const char *func_names[] = { "a","b","c" };
Хотя можно удалить а, б, в дублирования и что-то вроде:
//the_header.h
typedef int intfunc_t(int); /*function not function pointer*/
#define FUNC a,b,c
intfunc_t FUNCS; /*prototypes*/
//collector.c
#include "the_header.h"
const intfunc_t *func_ptrs[] = { FUNCS };
const char *func_names[] = { STRINGIFY_EACH(FUNCS) };
Реализация STRINGIFY_EACH требует какую-то темную магию макросъемки (AFAIK), такие как:
#define STRINGIFY_EACH(...) MC_foreachc(MC_str, __VA_ARGS__)
#define MC_str(_d) MC_str_impl_(_d)
#define MC_str_impl_(s) #s
#define MC_foreachc(What, ...) MC_foreachc_(MC_argc(__VA_ARGS__), What, __VA_ARGS__)
/* MC_foreachc(foo, a,b,c) foo(a), foo(b), foo(c); */
#define MC_foreachc_0(What, x, ...)
#define MC_foreachc_1(What, x, ...) What(x)
#define MC_foreachc_2(What, x, ...) What(x) , MC_expand(MC_foreachc_1(What, __VA_ARGS__))
#define MC_foreachc_3(What, x, ...) What(x) , MC_expand(MC_foreachc_2(What, __VA_ARGS__))
#define MC_foreachc_4(What, x, ...) What(x) , MC_expand(MC_foreachc_3(What, __VA_ARGS__))
#define MC_foreachc_5(What, x, ...) What(x) , MC_expand(MC_foreachc_4(What, __VA_ARGS__))
#define MC_foreachc_6(What, x, ...) What(x) , MC_expand(MC_foreachc_5(What, __VA_ARGS__))
#define MC_foreachc_7(What, x, ...) What(x) , MC_expand(MC_foreachc_6(What, __VA_ARGS__))
#define MC_foreachc_8(What, x, ...) What(x) , MC_expand(MC_foreachc_7(What, __VA_ARGS__))
#define MC_foreachc_9(What, x, ...) What(x) , MC_expand(MC_foreachc_8(What, __VA_ARGS__))
#define MC_foreachc_10(What, x, ...) What(x) , MC_expand(MC_foreachc_9(What, __VA_ARGS__))
#define MC_foreachc_11(What, x, ...) What(x) , MC_expand(MC_foreachc_10(What, __VA_ARGS__))
#define MC_foreachc_12(What, x, ...) What(x) , MC_expand(MC_foreachc_11(What, __VA_ARGS__))
#define MC_foreachc_13(What, x, ...) What(x) , MC_expand(MC_foreachc_12(What, __VA_ARGS__))
#define MC_foreachc_14(What, x, ...) What(x) , MC_expand(MC_foreachc_13(What, __VA_ARGS__))
#define MC_foreachc_15(What, x, ...) What(x) , MC_expand(MC_foreachc_14(What, __VA_ARGS__))
#define MC_foreachc_16(What, x, ...) What(x) , MC_expand(MC_foreachc_15(What, __VA_ARGS__))
#define MC_foreachc_17(What, x, ...) What(x) , MC_expand(MC_foreachc_16(What, __VA_ARGS__))
#define MC_foreachc_18(What, x, ...) What(x) , MC_expand(MC_foreachc_17(What, __VA_ARGS__))
#define MC_foreachc_19(What, x, ...) What(x) , MC_expand(MC_foreachc_18(What, __VA_ARGS__))
#define MC_foreachc_20(What, x, ...) What(x) , MC_expand(MC_foreachc_19(What, __VA_ARGS__))
#define MC_foreachc_21(What, x, ...) What(x) , MC_expand(MC_foreachc_20(What, __VA_ARGS__))
#define MC_foreachc_22(What, x, ...) What(x) , MC_expand(MC_foreachc_21(What, __VA_ARGS__))
#define MC_foreachc_23(What, x, ...) What(x) , MC_expand(MC_foreachc_22(What, __VA_ARGS__))
#define MC_foreachc_24(What, x, ...) What(x) , MC_expand(MC_foreachc_23(What, __VA_ARGS__))
#define MC_foreachc_25(What, x, ...) What(x) , MC_expand(MC_foreachc_24(What, __VA_ARGS__))
#define MC_foreachc_26(What, x, ...) What(x) , MC_expand(MC_foreachc_25(What, __VA_ARGS__))
#define MC_foreachc_27(What, x, ...) What(x) , MC_expand(MC_foreachc_26(What, __VA_ARGS__))
#define MC_foreachc_28(What, x, ...) What(x) , MC_expand(MC_foreachc_27(What, __VA_ARGS__))
#define MC_foreachc_29(What, x, ...) What(x) , MC_expand(MC_foreachc_28(What, __VA_ARGS__))
#define MC_foreachc_30(What, x, ...) What(x) , MC_expand(MC_foreachc_29(What, __VA_ARGS__))
#define MC_foreachc_31(What, x, ...) What(x) , MC_expand(MC_foreachc_30(What, __VA_ARGS__))
#define MC_foreachc_32(What, x, ...) What(x) , MC_expand(MC_foreachc_31(What, __VA_ARGS__))
#define MC_foreachc_(N, What, ...) MC_expand(MC_cat(MC_foreachc_, N)(What, __VA_ARGS__))
Это не представляется возможным с C препроцессор. Я бы рекомендовал написать программу, которую вы запускаете во время сборки, которая сканирует ваши источники для 'FUNC (foo)' или какого-либо другого маркера и генерирует нужные вам списки. – zwol
Спасибо @zwol. Я добавил пояснение внизу, что это не _have_ как массив. Это открывает возможность, например, для создания более децентрализованного подхода со связанными списками. Может ли это работать? Например, 'FUNC' расширяет функцию и линию, которая создает новый объект« Node »и добавляет себя в конец связанного списка всех существующих объектов« Node ». И тогда одна строка в начале объявляет 'head' ... – BeeOnRope
, это все еще невозможно, потому что нет способа получить имя объекта _previous_' Node', чтобы связать себя. Вероятно, вы предполагали, что только одно объявление в заголовке списка нуждается в имени, но это не сработает, потому что вы не можете изменить значение уже инициализированного постоянного объекта позже в файле. – zwol