Вне функции вы можете использовать выражение инициализатора только для присвоения значения глобальной (или статической или bss) переменной.
Это, в свою очередь, означает, что используемое вами выражение инициализатора должно инициализировать всемассив сразу, например так:
static int test[] = { 4, 5, 6 };
, который, конечно, может быть расширен до произвольных данных, таких как указатели функций или структуры
void some_func0(const char *v) { }
void some_func1(const char *v) { }
static void (*test[])(const char *) = { &some_func0, &some_func1 };
.Однако, как вы можете видеть, для этого требуется, чтобы все функции, которые вы намеревались использовать, были по крайней мере объявлены перед инициализатором.В точке объявления массива в вашем вопросе (в "device.h") я предполагаю, что вы не знаете всех реализаций.
Однако вам нужен исходный файл где-нибудь в вашей программе, где вызнаю все элементы массива одновременно.Чтобы обойти это, вы можете реструктурировать свой код следующим образом:
device.h
extern void (*test[])(const char *); // <-- or your struct type
vga.h
extern void vga_write(const char *);
vga.c
void vga_write(const char *c) {...
device_array_initialization_helper_this_is_a_very_verbose_file_name.c
#include "device.h"
#include "vga.h"
// Definition of the array, which is declared in device.h
void (*test[])(const char *) = { &vga_write, ... };
Конечно, вы также можете использовать свой тип структуры.