Можно ли выполнить функцию на инициализации в c?

Существует ли механизм или прием для выполнения функции когда загрузки программы?

Чего я пытаюсь достигнуть...

void foo(void)
{
}

register_function(foo);

но очевидно register_function не будет работать.

таким образом, прием в C++ должен использовать инициализацию для создания функции выполненной

что-то как

int throwaway = register_function(foo);

но это не работает в C. Таким образом, я ищу путь вокруг этого стандарта использования C (ничто платформа / конкретный компилятор)

6
задан bdonlan 21 June 2010 в 03:50
поделиться

3 ответа

Если вы используете GCC, вы можете сделать это с помощью атрибута функции конструктора, например:

#include <stdio.h>

void foo() __attribute__((constructor));

void foo() {
    printf("Hello, world!\n");
}

int main() { return 0; }

Однако в Си нет переносимого способа сделать это.

Однако если вы не против возиться с вашей системой сборки, у вас есть больше возможностей. Например, вы можете:

#define CONSTRUCTOR_METHOD(methodname) /* null definition */

CONSTRUCTOR_METHOD(foo)

Теперь напишите сценарий сборки для поиска экземпляров CONSTRUCTOR_METHOD и вставьте последовательность вызовов этих экземпляров в функцию в сгенерированном .c файле. Вызовите сгенерированную функцию в начале main().

15
ответ дан 8 December 2019 в 12:57
поделиться

Стандартного способа сделать это не существует, хотя gcc предоставляет атрибут конструктор для функций.

Обычный способ обеспечения выполнения некоторой предварительной настройки (кроме простой инициализации переменной значением времени компиляции) - убедиться, что все функции, требующие этой предварительной настройки.Другими словами, что-то вроде:

static int initialized = 0;
static int x;

int returnX (void) {
    if (!initialized) {
        x = complicatedFunction();
        initialized = 1;
    }
    return x;
}

Это лучше всего делать в отдельной библиотеке, поскольку это изолирует вас от реализации.

0
ответ дан 8 December 2019 в 12:57
поделиться

Стандарт C не поддерживает такую операцию. Если вы не хотите использовать для этого специфические возможности компилятора, то лучшим вариантом будет создание глобального статического флага, который инициализируется в false. Тогда всякий раз, когда кто-то вызывает одну из ваших операций, требующих регистрации указателя функции, вы проверяете этот флаг. Если он равен false, вы регистрируете функцию, а затем устанавливаете флаг в true. Последующие вызовы не должны будут выполнять регистрацию. Это похоже на ленивое инстанцирование, используемое в шаблоне проектирования OO Singleton.

3
ответ дан 8 December 2019 в 12:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: