2

我有以下代码布局

头文件.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 文件时,它工作正常。我一直认为在标题中声明它是要走的路。

4

3 回答 3

4

我一直认为在标题中声明它是要走的路。

是的。在标题中声明它很好。但是,在标题中定义它并不是什么好事。(除非它是static inline,但这些天你可能不想这样做。)

于 2014-06-10T15:03:07.537 回答
3

您永远不应该在头文件中包含需要在运行程序中使用内存的东西。这是一种粗略的指定方式,但在实践中效果很好。

换句话说,头文件应该只有函数的原型,这是一个编译时的东西,在运行的程序中并不“存在”(不像函数本身的代码,它当然存在于运行时):

void empty(float *array, int l);

然后将代码放在一个单独的 C 文件中,您可以单独编译和链接该文件。

于 2014-06-10T15:03:11.433 回答
1

您将函数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

于 2014-06-10T15:03:22.350 回答