Это происходит потому, что ваш компилятор C встраивает каждый файл .c в объектный (.o) файл, а затем связывает объектные файлы, чтобы сделать исполняемый файл.Содержимое файла .c и всех включаемых в него файлов известны как единица компиляции .
В вашем примере есть две единицы компиляции:
main.c
, включая stdio.h
и a.h
→ компилируется в main.o
a.c
, включая a.h
→ компилируется в ao
Затем компоновщик (ld) пытаетсясвязать файлы .o, но обнаруживает, что они оба определяют square()
, потому что он был в общем a.h
- отсюда и ошибка.Вот почему, как некоторые уже отметили, вы не должны помещать определения функций в заголовки.
Если у вас установлена утилита nm
(которая должна быть у вас), вы можете запустить
$ nm main.o
$ nm a.o
в оболочке, чтобы увидеть, что square
существует в обоих файлах.
(Edit: термин, о котором я думал, на самом деле был единица перевода , но при поиске вокруг они кажутсязначить почти то же самое.)