Я разрабатываю ядро ОС как хобби, и у меня уже есть библиотека, которая заменяет стандартную библиотеку как в размещенной, так и в автономной среде. Естественно, он обеспечивает точку входа, которая выполняет необходимую настройку и вызывает main()
.
В размещенной среде кажется, что не имеет значения, совпадают ли подписи объявления main()
и фактического определения main()
. Однако, как только я добавлю флаг компиляции -ffreestanding
, компоновщик больше не сможет разрешить такую ссылку. См. Минимальный пример ниже:
start.cpp
int main(int argc, char *argv[], char *envp[]);
extern "C" void _start()
{
main(0, nullptr, nullptr);
}
main.cpp
int main()
{
return 0;
}
Командная строка:
clang++-6.0 -nostdlib -ffreestanding start.cpp main.cpp
Похоже, что такое поведение характерно для Clang, поскольку GCC 7.3.0 успешно компилирует этот пример.
Мой вопрос в том, как приведенный выше пример разрешен и работает в целом, и является ли проблема, с которой я сталкиваюсь, ошибкой Clang.
Обновление 1:
Оказалось, что решение этой проблемы - добавить __attribute__((weak))
к объявлению main()
. Однако было бы неплохо, если бы кто-нибудь мог более подробно объяснить, как это обычно работает с main()
.
Обновление 2:
Очевидно, маркировка main()
как слабого символа делает возможным связывание без main()
вообще, что, очевидно, не так, как это обычно работает (с учетом всех других «неопределенных ссылок на основные» вопросы по SO). Итак, если main()
обычно не является слабым символом, как он на самом деле работает?
Обновление 3:
Оказывается, слабый символ вообще не является решением, потому что при использовании с -ffreestanding
он только скрывает тот факт, что int main(int argc, char *argv[], char *envp[])
никогда не разрешается, а фактический int main()
вообще не вызывается из _start()
. Однако в размещенной среде он по-прежнему вызывается как обычно. Это все больше и больше похоже на ошибку Clang.
main()
в автономной среде - или, может быть, это по дизайну, что в автономной среде env main не является особенным. - person SergeyA   schedule 15.10.2018__attribute__((weak))
, который лишь смутно упоминается в третьем ответе на повторяющийся вопрос. - person r3mus n0x   schedule 15.10.2018main
выделяется среди других символов, и существуют некоторые правила обращения с ним. Я думаю, что сделать его слабым символом с другой подписью - значит сыграть с огнем. Я думаю, что правильный способ делать то, что вы хотите, - использовать определения препроцессора. Что касается вашего вопроса ... если main () обычно не является слабым символом, как это действительно работает?, см. Требуется ли main () для программы C? и, возможно, Избегание main (точки входа) в программе C < / а>. - person jww   schedule 16.10.2018-ffreestanding
или это ошибка компилятора. - person r3mus n0x   schedule 16.10.2018first_main
иsecond_main
, но у меня нет двух основных функций. У меня есть только объявление в одном файле и определение в другом. - person r3mus n0x   schedule 16.10.2018main
слабым, если только он не предназначен для переопределения при случае (подразумевая две реализации). Я, наверное, должен просто уйти сейчас. - person jww   schedule 16.10.2018