Что такое _start() в C?
Я узнал от своего коллеги, что можно писать и выполнять программу на C без написания функции main()
. Это можно сделать как под
withoutMain.c
// Compile it with gcc -nostartfiles
void _start() {
int ret = my_main();
exit(ret);
}
int my_main() {
puts("This is a program without main!\n");
return 0;
}
Скомпилируйте его как:
gcc -o withoutMain withoutMain.c –nostartfiles
Запустите его как:
./ withoutMain
Мой вопрос: когда нужно будет делать такие вещи? Какой-то реальный сценарий?
Ответы
Ответ 1
Символ _start
- это точка входа вашей программы. То есть, адрес этого символа - это адрес, с которым он перешел в начало программы. Обычно функция с именем _start
предоставляется файлом с именем crt0.o
, который содержит код запуска среды выполнения C. Он создает некоторые вещи, заполняет массив аргументов argv
, подсчитывает, сколько аргументов есть, а затем вызывает main
. После возврата main
вызывается exit
.
Если программа не хочет использовать среду выполнения C, ей необходимо предоставить свой собственный код для _start
. Например, эталонная реализация языка программирования Go делает это потому, что им нужна нестандартная модель потоковой передачи, которая требует некоторой магии со стеком. Он также полезен для предоставления собственных _start
, когда вы хотите писать действительно крошечные программы или программы, которые делают нетрадиционные вещи.
Ответ 2
Хотя main
является точкой входа для вашей программы с точки зрения программистов, _start
является обычной точкой входа с точки зрения ОС (первая инструкция, которая запускается после запуска вашей программы из ОС)
В типичной программе C и особенно С++ большая работа была выполнена до того, как выполнение вступит в основное. Особенно такие вещи, как инициализация глобальных переменных. Здесь вы можете найти хорошее объяснение всего, что происходит между _start()
и main()
, а также после того, как main снова вышел (см. комментарий ниже).
Необходимый код для этого обычно предоставляется авторами компилятора в файле автозагрузки, но с флагом –nostartfiles
вы по существу говорите компилятору: "Не утруждайте себя предоставлением стандартного файла запуска, дайте мне полный контроль над тем, что происходит с самого начала".
Это иногда необходимо и часто используется для встроенных систем. Например. если у вас нет ОС, и вы должны вручную включить определенные части вашей системы памяти (например, кеши) до инициализации ваших глобальных объектов.