Ошибка дублированного символа в 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 определяется как глобальный символ в заголовке. Это означает, что он будет видимым символом во всех единицах компиляции, которые его включают. Есть три основных обходных пути:

  1. сделать это статической функцией

    static void empty(...) {...}
    
  2. поместить реализацию в отдельную единицу компиляции

    в header.h:

    void empty(float *array, int l);
    

    в empty.c реализовать это

  3. поручите вашему компоновщику игнорировать повторяющиеся символы. Это отличается от компоновщика к компоновщику, проконсультируйтесь man ld,

    На OS X: -m флаг.

    В Linux: -z muldefs

Другие вопросы по тегам