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

Ошибка implicit declaration of function

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

Сообщение значит: функция вызвана, но компилятор ни разу не видел её объявления выше этого места. Чаще всего забыт #include, функция написана ниже main или в имени опечатка. Так выглядит сообщение gcc:

Текст
main.c: In function 'main':
main.c:2:5: warning: implicit declaration of function 'printf' [-Wimplicit-function-declaration]
main.c:1:1: note: include '<stdio.h>' or provide a declaration of 'printf'

До gcc 14 это предупреждение (warning), и программа даже собирается, начиная с gcc 14 — ошибка (error). В macOS компилятор clang пишет то же другими словами: call to undeclared function 'printf'. Исправлять нужно в любом случае.

Как исправить

Посмотрите на имя функции в сообщении: стандартная ли это функция C (printf, strlen, sqrt…), ваша собственная или имя с опечаткой либо из старого учебника.

Стандартная функциязабыт #include

Стандартные функции объявлены в заголовочных файлах. gcc часто сам подсказывает нужный строкой note: include ….

ФункцииЗаголовок
printf, scanf, fopen, fgets, puts#include <stdio.h>
malloc, free, rand, srand, abs, atoi, qsort, exit#include <stdlib.h>
strlen, strcpy, strcat, strcmp, memset, memcpy#include <string.h>
sqrt, pow, fabs, round, floor, ceil#include <math.h>
isdigit, isalpha, toupper, tolower#include <ctype.h>
time, clock#include <time.h>

Дальше: «Почему нельзя просто не обращать внимания»

Своя функция ниже mainнужен прототип

Компилятор читает файл сверху вниз. Если функция написана после main, в момент вызова она ещё неизвестна:

Текст
#include <stdio.h>

int main(void) {
    printf("%d\n", square(3));   // square здесь ещё не объявлена
    return 0;
}

int square(int x) {
    return x * x;
}

Решение — поставить выше main прототип (заголовок функции с точкой с запятой) или перенести всю функцию выше main:

C
#include <stdio.h>

int square(int x);

int main(void) {
    printf("%d\n", square(3));
    return 0;
}

int square(int x) {
    return x * x;
}
Вывод
9

Если функция в другом файле, её прототип выносят в свой заголовочный файл (utils.h) и подключают его: #include "utils.h" — в кавычках, а не в угловых скобках.

Дальше: «Почему нельзя просто не обращать внимания»

Опечатка или функция не из стандарта

  • Опечатка: prinft, scnaf, strlenght. gcc иногда подсказывает: did you mean 'printf'?.
  • Функции не из стандарта C. getch и clrscr из conio.h, itoa, strrev встречаются в старых учебниках, но есть только в некоторых компиляторах для Windows. В Linux и в macOS их нет. Замены: вместо getch() для паузы — getchar(), вместо itoa — snprintf(buf, sizeof(buf), "%d", n), вместо strrev — свой цикл (пример в уроке Строки).

Почему нельзя просто не обращать внимания

Если gcc до 14-й версии собрал программу с этим предупреждением, он считает, что функция возвращает int и принимает любые аргументы. Если на самом деле она возвращает double или указатель, результат может оказаться испорчен. А если функции нет вовсе (опечатка), сборка всё равно остановится на шаге связывания с ошибкой undefined reference — разбор в справке undefined reference.