Ошибка дублированного символа в C
У меня есть следующий макет кода
header.h
#ifndef _header_h
#define _header_h
void empty(float *array, int l)
{
int i;
for (i=1 ; i<=l ; i++)
{
array[i]=0;
}
}
#endif
и два файла (назовем их file1.c и file2.c)
#include "header.h"
void function/*1 or 2*/(){
....
empty(a,b);
....
}
Таким образом, компиляция работает нормально, но команда компоновщика завершается неудачно, так как компилятор говорит, что существует дублированное определение функции. Как я могу избежать этого, все еще используя файл заголовка? Это работает нормально, когда я только определяю функцию в заголовке и создаю другой файл.c, содержащий полную функцию. Я всегда думал, что объявление этого в заголовке - путь.
3 ответа
Я всегда думал, что объявление этого в заголовке - путь.
Да, это. Объявление его в шапке нормально. Впрочем, определять его в заголовке не очень хорошо. (если это не static inline
, но вы, вероятно, не хотите делать это в эти дни.)
Вы никогда не должны иметь в заголовке вещи, которые требуют памяти в работающей программе. Это грубый способ указать его, но на практике он работает довольно хорошо.
Другими словами, заголовок должен иметь только прототип для функции, которая во время компиляции не "существует" в работающей программе (в отличие от кода самой функции, который, конечно, существует во время выполнения):
void empty(float *array, int l);
Затем поместите код в отдельный файл C, который вы компилируете и отдельно связываете.
У вас есть функция empty
определяется как глобальный символ в заголовке. Это означает, что он будет видимым символом во всех единицах компиляции, которые его включают. Есть три основных обходных пути:
сделать это статической функцией
static void empty(...) {...}
поместить реализацию в отдельную единицу компиляции
в
header.h
:void empty(float *array, int l);
в
empty.c
реализовать этопоручите вашему компоновщику игнорировать повторяющиеся символы. Это отличается от компоновщика к компоновщику, проконсультируйтесь
man ld
,На OS X:
-m
флаг.В Linux:
-z muldefs