Глиф Учебники

undefined reference to main и другие undefined reference

Справочник · C · 2 минуты чтения

undefined reference — ошибка не компилятора, а компоновщика (линкера, программы ld). Он собирает готовый исполняемый файл из частей и не нашёл функцию, которую кто-то вызывает. Сообщение заканчивается строкой collect2: error: ld returned 1 exit status — это просто итог: компоновка не удалась.

Как читать сообщение

Компоновщик пишет, из какой функции вызов и чего не хватает:

Текст
/usr/bin/ld: /tmp/ccA1b2C3.o: in function `main':
main.c:(.text+0x1e): undefined reference to `square'

Здесь вызов стоит в функции main файла main.c, а не найдена функция square.

Что делать

Решение зависит от имени, которое стоит после undefined reference to.

main или WinMainне найдена главная функция

Текст
/usr/bin/ld: ... in function `_start':
(.text+0x1b): undefined reference to `main'
collect2: error: ld returned 1 exit status

Компоновщик не нашёл функцию main, с которой начинается программа. Причины:

  • Опечатка в имени. Main, mian, main1 — C различает большие и маленькие буквы, нужно ровно main.
  • Файл не сохранён. Редактор показывает программу, а на диске пустой файл или старая версия. Сохраните (Ctrl+S) и соберите заново.
  • Собирается не тот файл. В команде gcc указан другой файл, или в проекте среды разработки файла с main нет (он открыт, но не добавлен в проект).
  • Файл без main собирают как программу. Если в файле только функции для другой программы, собирайте его вместе с основным: gcc main.c utils.c -o prog.

В Windows (MinGW) та же ошибка выглядит как undefined reference to 'WinMain' или 'WinMain@16': если main не нашлась, компоновщик ищет WinMain — главную функцию оконных программ — и тоже не находит. Причины те же.

sqrt, pow и другие из math.hнужен ключ -lm

Текст
undefined reference to `sqrt'

В Linux математические функции лежат в отдельной библиотеке, и её нужно подключить ключом -lm в конце команды:

Bash
gcc prog.c -o prog -lm

Ключ ставится после имени файла: компоновщик просматривает библиотеки по порядку, и -lm перед prog.c может не помочь. Интересно, что sqrt(16.0) с числом в скобках часто собирается и без -lm — компилятор считает такой корень сам. А sqrt(x) с переменной требует библиотеку.

Другая функциясвоя или нестандартная

Если функция ваша, ищите её определение: есть ли оно, так ли написано имя и попадает ли файл с ним в сборку.

  • Функция в другом файле, а он не собирается. Перечислите все файлы: gcc main.c utils.c -o prog. В Code::Blocks и Visual Studio проверьте, что файл добавлен в проект.
  • Есть только прототип. Строка int square(int x); обещает, что функция где-то есть, но тела у неё нет. Напишите функцию.
  • Опечатка. В вызове Square, в определении square — для C это разные функции. Обычно перед этим gcc ещё и предупреждает: implicit declaration of function — см. справку implicit declaration of function.
  • Нестандартная функция. getch, itoa, strrev есть не во всех системах. Если заголовок нашёлся, а библиотеки с функцией нет, ошибка выйдет на компоновке.