Multiple definition of ... linker error

153,827

Solution 1

Don't define variables in headers. Put declarations in header and definitions in one of the .c files.

In config.h

extern const char *names[];

In some .c file:

const char *names[] = { 
  "brian", "stefan", "steve" };

If you put a definition of a global variable in a header file, then this definition will go to every .c file that includes this header, and you will get multiple definition error because a varible may be declared multiple times but can be defined only once.

Also, one more thing you can do if you have to define your variables inside of a header file you can use the static keyword.

static const char *names[] = {
  "brian", "stefan", "steve" };

This way variable names will be defined only once in your entire program and can be accessed multiple number of times.

Solution 2

Declarations of public functions go in header files, yes, but definitions are absolutely valid in headers as well! You may declare the definition as static (only 1 copy allowed for the entire program) if you are defining things in a header for utility functions that you don't want to have to define again in each c file. I.E. defining an enum and a static function to translate the enum to a string. Then you won't have to rewrite the enum to string translator for each .c file that includes the header. :)

Share:
153,827
mazix
Author by

mazix

Updated on February 07, 2022

Comments

  • mazix
    mazix over 2 years

    I defined a special file: config.h

    My project also has files:

    t.c, t.h
    pp.c, pp.h
    b.c b.h
    l.cpp
    

    and #includes:

    in t.c:

        #include "t.h"
        #include "b.h"
        #include "pp.h"
        #include "config.h"
    

    in b.c:

        #include "b.h"
        #include "pp.h"
    

    in pp.c:

        #include "pp.h"
        #include "config.h"
    

    in l.cpp:

        #include "pp.h"
        #include "t.h"
        #include "config.h"
    

    there are no include directives in my *.h files, only in *.c files. I defined this in config.h:

    const char *names[i] =
            {
                "brian", "stefan", "steve"
            };
    

    and need that array in l.cpp, t.c, pp.c but Im getting this error:

    pp.o:(.data+0x0): multiple definition of `names'
    l.o:(.data+0x0): first defined here
    t.o:(.data+0x0): multiple definition of `names'
    l.o:(.data+0x0): first defined here
    collect2: ld returned 1 exit status
    make: *** [link] Error 1
    

    I have include guards in every *.h file I use in my project. Any help solving this?

  • mazix
    mazix almost 11 years
    solved! :) Could you please tell me why I shouldnt put declarations in h*. files?
  • Jiminion
    Jiminion almost 11 years
    So it won't do this. Use *.h files just to reference information. You have to remember that "include" means it is including all the *.h information in that file, so you would be copying that information (not just the reference) into every file using the *.h. This can get linkers confused, and does.
  • Yu Hao
    Yu Hao almost 11 years
    @mazix No, the definition of a global varible should go to .c file, and put the declaration in the header. Remember that you can declare a varible many times but define it only once.
  • Spalteer
    Spalteer almost 11 years
    Just to make the explanation slightly clearer, the header file is likely to be included in more than one c file, so you'll end up with several declarations of a variable with the same name
  • Saik
    Saik about 7 years
    I actually find this answer far more convenient than the top answer. It is more convenient and appealing just to have one header to store all global variables for example, instead of having .h and .cpp files. Thank you.
  • Alejandro Galera
    Alejandro Galera about 6 years
    I think also this solution is better than the most voted because the other needs to define values in each *.c file, and furthermore yours, @JonathanWhittenberg, looks more elegant. Thanks a lot
  • Ebrahim Karimi
    Ebrahim Karimi over 5 years
    is it possible to use extern for class constructor?
  • SimonC
    SimonC over 5 years
    Better and more elegant solution than the AA. +1 for adding why it's not always a bad idea.
  • Kotauskas
    Kotauskas about 5 years
    The extern is actually redundant: extern linkage is the default.
  • PPenguin
    PPenguin about 5 years
    This isn't an accurate description of what static does. "You may declare the definition as static (only 1 copy allowed for the entire program)" NO! static makes the definition scoped to that compile unit. So it gives you one copy per compile unit. So if you have some large list of strings, your program will end up having many duplicate copies of this list ... one for each c file. This is even worse for static functions if you later go to debug this, because there is no longer a single function to place a breakpoint on, but many copies of that function in the resulting linked program.
  • Admin
    Admin over 2 years
    Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.