Я только учусь C ++. Компиляция с g ++ версии 3.2.3, «g ++ hworld.cpp»:
double sqrt(double);
int main(){
double x = sqrt(1515.15);
return 0;
}
Это прекрасно компилируется, но если бы мы заменили sqrt на «sqrtfoo», компилятор сказал бы, что sqrtfoo нельзя использовать в качестве функции. Я думал, что мне придется включить cmath, но я думаю, нет? Может кто-нибудь объяснить, к чему у моей программы есть доступ, прежде чем включать? Для сравнения, gcc не позволяет мне делать это, говоря «неопределенная ссылка на« sqrt »». Спасибо.
Как объясняют существующие ответы, double sort(double)
предоставляет прототип, чтобы компилятор знал, что функция существует.
Но вы также упомянули, что это не работает в GCC. Когда вы создаете программу на C или C ++, исходный код компилируется в объектный формат. Объектные файлы затем связываются вместе, чтобы сформировать исполняемый файл.
Чтобы увидеть это в действии, попробуйте
gcc -c hello.c
Это говорит GCC скомпилировать (-c) исходный файл hello.c. Предполагая, что hello.c существует и не имеет ошибок, вы найдете hello.o в текущем каталоге. Сейчас попробуй
gcc -o hello hello.o
Это говорит GCC связать hello.o с соответствующими системными библиотеками и сгенерировать выходной файл с именем «hello». Если hello.c использует математические функции, вам также необходимо добавить ссылку в математическую библиотеку:
gcc -o hello hello.o -lm
«-l» используется для указания gcc на включение дополнительных библиотек (кроме стандартной библиотеки «libc» C). «m» относится к «libm», который является математической библиотекой, содержащей sqrt
, Если ваша программа использует только один исходный файл, обычно неявно просят GCC скомпилировать и связать в одной команде:
gcc -o hello hello.c -lm
Теперь к вашему вопросу. GCC не скомпилирует приведенный выше код, потому что вы не попросили его добавить ссылку в математическую библиотеку. Но с g ++ все в порядке. Там очень аналогичный вопрос уже на переполнении стека. Согласно принятому ответу,
среда выполнения C ++ libstdc ++ требует libm, поэтому, если вы компилируете C ++
Программа с GCC (g ++), вы автоматически получите libm, связанный с.
Поскольку libstdc ++ — это библиотека времени выполнения языка C ++, она по умолчанию включена в g ++. И поскольку это зависит от libm, компоновщик автоматически загружает libm при создании окончательной двоичной программы.
Вам не нужно включать cmath
потому что ваш код имеет прототип для sqrt
в ней уже самая первая строчка.
Заголовочные файлы содержат только объявления (подписи), и вы включили их в первую строку (прототип: double sqrt(double)
).
Компилятор компилирует его просто отлично, потому что вы заявили, что где-то эта функция определена. Шаг, который происходит после компиляции, отвечает за фактический поиск этого определения функции. Это называется linking
и на этом этапе компоновщик ищет эти определения. В случае sqrtfoo
он не может ничего найти, тогда как в случае sqrt
это находит это в некоторой стандартной библиотеке (я не знаю детали здесь).