Когда вы включаете файл, включаемый файл заменяется содержимым файла (и это продолжается до тех пор, пока больше нет включений).
- Если
main.c
и lib.c
оба включают lib.h
, тогда у них обоих есть отдельные копии lib.h
, скомпилированные в. - Если
lib.h
включает primes.h
, то у них обоих есть свои собственные отдельные копии primes.h
, скомпилированные в. - Если
primes.h
имеет определенный массив, то у них обоих есть копия этого массива. - И если у них обоих есть что-то с одинаковыми именами, определенными в обоих файлах, вы получите дублирующую ошибку определения.
Лучший способ исправить это - иметь только 1 определение массива primes
со всеми его значениями в исходном файле (например, lib.c
), и вам нужно использовать extern
ключевое слово в primes.h
без значений, чтобы объявить, что один из ваших файлов содержит фактический массив (в этом случае вы можете не указывать размер). Обратите внимание, что использование ключевого слова extern
является своего рода обещанием для компилятора, что существует некоторый файл, содержащий фактический массив, и поэтому вам все еще нужен фактический массив в исходном файле:
// primes.h
extern uint64_t primes[];
// lib.c
#include "primes.h"
uint64_t primes[] = {
7,
11,
};
// main.c
#include "primes.h"