Вопрос
Я хочу иметь код, который выглядит примерно так...
static linked_list* globalListHoldingAllSortsOfGoodies = initialize_linked_list();
/* [In a different file...] */
static int placeholder = add_to_global_list(goodies);
Но непостоянная инициализация невозможна в C.
Есть ли способ добиться того же эффекта, не нарушая C89?
Суть в том, чтобы разные вещи «автоматически регистрировались» в глобальном списке, объявляя полезные вещи с помощью макроса, который также использует заполнитель.
Решение
Вы можете построить связанный список из статических данных.В ANSI C89 (он же ISO C90) это может выглядеть так:
struct node
{
int data;
struct node *next;
};
struct node nodes[] = { { 42, &nodes[1] }, { 137, 0 } };
struct node *list = nodes;
В ISO C99 (принятом ANSI в 2000 году) можно дополнительно использовать составные литералы, например
struct node *list = &(struct node){ 42, &(struct node){ 137, 0 } };
Смешивание статически выделенных узлов с динамически выделенными узлами проблематично, поскольку освобождение первых приведет к неопределенному поведению, поэтому необходимо будет отслеживать, какие узлы принадлежат к какой группе.
Другие советы
Ну, вы можете инициализировать placeholder
в main
метод :-)
Нет, такого не существует.Вы можете инициализировать статические переменные статическими данными.Добавление в список не является «статичным».Я считаю, что большинство людей пишут препроцессор, который сканирует исходные файлы, находит нужные вещи в «глобальном списке», а затем генерирует файл .c с соответствующими данными (например,статически инициализированная таблица с завершающим NULL).
Как вы заметили, C не имеет такой возможности.Если вы не можете сделать это вне C (путем создания кода C), то альтернативой может быть создание функции Initialize() для каждого модуля, который в ней нуждается, и обеспечение вызова функций в нужное время.