Подтвердить что ты не робот

Выполнение кода перед main()

В объектно-ориентированных языках (С++) вы можете выполнить код до main() с помощью глобального объекта или статического объекта класса и иметь их конструкторы для запуска кода, который вы хотите.

Есть ли способ сделать это в C? У меня нет конкретной проблемы, которую я пытаюсь решить, мне просто интересно. Одно может быть полезно для автоматической инициализации библиотеки.

4b9b3361

Ответ 1

Существуют способы использования __attribute__ но они очень специфичны для вашего компилятора, и код, написанный с их использованием, на самом деле не переносим. С другой стороны, язык Си не предоставляет никаких стартовых модулей/библиотек.

В C логически main() является первой функцией, вызываемой ОС. Но перед вызовом main() ОС вызывает другую функцию, называемую модулем start-up для установки различных переменных среды, инициализации (неинициализированных) статических переменных, построения стекового фрейма (записи активации) и инициализации указателя стека на начало область стека и другие задачи, которые необходимо выполнить перед вызовом main().

Скажем, если вы пишете код для встраиваемых систем, где нет ни одной минимальной ОС для выполнения вышеупомянутой работы, то вам следует изучить эти параметры, которые зависят от компилятора. Помимо компиляторов GCC, Turbo-C и Microsoft C предоставляют средства для добавления кода на конкретную аппаратную машину (например, машины 8086).

Другими словами, модули запуска не предназначены для программистов.

Ответ 2

Вы можете сделать это с помощью __attribute__ ((constructor)). Я протестировал следующий пример с gcc и clang. Это, как говорится, это не часть языка.

#include <stdio.h>

void __attribute__ ((constructor)) premain()
{
    printf("premain()\n");
}

int main(int argc, char *argv[])
{
    printf("main()\n");
    return 0;
}

Это делает следующее:

$ ./test
premain()
main()

GCC документирует это по адресу: https://gcc.gnu.org/onlinedocs/gcc-8.3.0/gcc/Common-Function-Attributes.html#Common-Function-Attributes.

Ответ 3

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

__attribute__ ((__constructor__)) 
void foo(void) {
        ...
}

Это вызовет foo перед основным.

Примечание. Это, вероятно, не переносимо для других компиляторов.

Ответ 4

Нет, вы не можете сделать это на C, и я бы сказал, что вы действительно не можете получить этот "код для выполнения до main()" даже в С++. Да, он может появляться до main() в script, но main() - это то, где программа действительно запускается.

Теперь вы можете инициализировать значения, что возможно. Вы также можете иметь переменные с заранее заданным состоянием, но это не одно и то же.

Ответ 5

Вы можете инициализировать глобальные переменные, но не вызывать функции внутри этих инициализаций.

Ответ 6

Не на любом стандартном уровне, но вы должны вникать в то, что действительно происходит, когда ваша операционная система загружает двоичное изображение и вызывает основную функцию приложения!

Ответ 7

Существуют переносные способы указания функций, которые могут быть выполнены "после выполнения" main.

Далее следуйте этой ссылке и о различных типах инициализации в С++ - это может быть полезно для вас выполнить код перед main() называется.