duplicate symbol error in C

2020-04-16 04:13发布

I have the following code layout

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

and two files (lets call them file1.c and file2.c)

#include "header.h"

void function/*1 or 2*/(){

     ....
     empty(a,b);
     ....
}

So compiling works fine but the linker command fails as the compiler says that there is a duplicate function definition. How can I avoid that with still using the header file? It is working fine when I only define the function in the header and create another .c file containing the full function. I always thought declaring it in the header is the way to go.

3条回答
劳资没心,怎么记你
2楼-- · 2020-04-16 04:51

You have the function empty defined as a global symbol in the header. This means it will be a visible symbol in all compilation units that include it. There are three general workarounds:

  1. make it a static function

    static void empty(...) {...}
    
  2. put the implementation into a separate compilation unit

    in header.h:

    void empty(float *array, int l);
    

    in empty.c implement it

  3. instruct your linker to ignore duplicate symbols. This differs from linker to linker, consult man ld.

    On OS X: -m flag.

    On Linux: -z muldefs

查看更多
狗以群分
3楼-- · 2020-04-16 04:55

I always thought declaring it in the header is the way to go.

Yes, it is. Declaring it in the header is fine. It is not any good to define it in a header, though. (unless it's static inline, but you probably don't want to do that these days.)

查看更多
The star\"
4楼-- · 2020-04-16 04:58

You should never have things in a header that require memory in the running program. This is a rough way of specifying it, but it works pretty well in practice.

In other words, the header should only have the prototype for the function, which is a compile-time thing that doesn't "exist" in the running program (unlike the code of the function itself, which of course exists at runtime):

void empty(float *array, int l);

Then put the code in a separate C file, which you compile and link separately.

查看更多
登录 后发表回答