Multiple definition and header-only libraries

Suugaku picture Suugaku · Nov 20, 2011 · Viewed 23.9k times · Source

I have a C program with several c and h files. I decided to make one part of the program 'header-only' so I moved the code from c to h. Now I'm getting multiples definition problems and I have no idea why. e.g.:

main.c includes utils.h
vector.c includes utils.h

I moved everything in utils.c to utils.h (and of course removed utils.c from the project). utils.h starts with

#ifndef UTILS_H_
#define UTILS_H_

// and end with:
#endif

To be sure my guard was unique I tried changing it (e.g.: UTILS718171_H_) but it doesn't work.

Still, the compiler complains:

/tmp/ccOE6i1l.o: In function `compare_int':
ivector.c:(.text+0x0): multiple definition of `compare_int'
/tmp/ccwjCVGi.o:main.c:(.text+0x660): first defined here
/tmp/ccOE6i1l.o: In function `compare_int2':
ivector.c:(.text+0x20): multiple definition of `compare_int2'
/tmp/ccwjCVGi.o:main.c:(.text+0x6e0): first defined here
/tmp/ccOE6i1l.o: In function `matrix_alloc':
ivector.c:(.text+0x40): multiple definition of `matrix_alloc'
/tmp/ccwjCVGi.o:main.c:(.text+0x0): first defined here
...

The problem might be something like: all c files are compiled and get their own version of the code and then at linkage it causes problem, but I have honestly no idea how to solve this problem.

Answer

Alok Save picture Alok Save · Nov 20, 2011

If you define your variables inside your header file and include the header in several c files, you are bound to get multiple definitions error because you break the One definition rule(ODR), which states that there should be only one definition in one Translation Unit(header files + source file).

Solution is:
You should define the entities you get Multiple definition errors for only once.
For Functions:
Declare the function prototypes in header file(which you include in other source files) and define the function in one and only one source file.
For Global variables:
You declare the variable extern in header file(which you include in other source files) and then define the variable in one and only one source file.