I have an array (C language) that should be initialized at compile time.
For example:
DECLARE_CMD(f1, arg);
DECLARE_CMD(f2, arg);
>
Yes, you can build dynamic arrays at compile time (not at runtime) (and thank's to Mitchel Humpherys), the idea is to declare your callbacks in the same section like this:
EXAMPLE:
Suppose you have three files a.c, b.c main.c and i.h
into i.h
typedef void (*my_func_cb)(void);
typedef struct func_ptr_s {
my_func_cb cb; /* function callback */
} func_ptr_t;
#define ADD_FUNC(func_cb) \
static func_ptr_t ptr_##func_cb \
__attribute((used, section("my_array"))) = { \
.cb = func_cb, \
}
into a.c
#include "i.h"
static void f1(void) {
....
}
ADD_FUNC(f1);
into b.c
#include "i.h"
static void f2(void) {
....
}
ADD_FUNC(f2);
into main.c
#include "i.h"
static void f3(void) {
....
}
ADD_FUNC(f3);
#define section_foreach_entry(section_name, type_t, elem) \
for (type_t *elem = \
({ \
extern type_t __start_##section_name; \
&__start_##section_name; \
}); \
elem != \
({ \
extern type_t __stop_##section_name; \
&__stop_##section_name; \
}); \
++elem)
int main(int argc, char *argv[])
{
section_foreach_entry(my_array, func_ptr_t, entry) {
entry->cb(); /* this will call f1, f2 and f3 */
}
return 0;
}
IMPORTANT
sometimes the compiler optimizes start/end sections variables, it wipes them out, so when you try to use them, you will have a linker error: error LNK2019: unresolved external symbol ...
to fix this problem, i use the following:
Try to print your linker script:
gcc -Wl,-verbose
copy the text between the two:
==================================================
in a file (example lnk.lds), you should see thing like:
/* Script for -z combreloc: combine and sort reloc sections */
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64","elf64-x86-64")
........
__start_my_array = .;
.my_array :
{
*(.my_array)
}
__stop_my_array = .;
Compile your program with the updated linker script like this:
gcc -O3 -Xlinker -T"lnk.lds" file.c -o program
If you type strings program | grep "__start_my_array" you should find it.