C/C++ >> multiple definitions using header files
Posted by Huxly on 00:26:00 10-06-2002
This is a Linux make question.
After defining
const char * title_file = "title.cdb";
in my header file, cd.h
I always get an error message during
the make compilation:
"multiple definitions of title_file"
I don't want to write out the entire
makefile but it uses cd.h for both
the main.c and getchoice.c.
I can't understand this. The title_file
is only defined once, in cd.h, but
the make programs says I've done
multiple definitions and won't create
an executable file. Duh?
Posted by buzgub on 15:01:00 10-09-2002
I'm fairly sure this is a link error. It also has to do with the difference between definitions and declarations.

pretend we have two files, "foo.c" and "bar.c".
Both of them do a #include "blah.h"
blah.h says "int magic_number = 20;"
now, it is as if foo.c and bar.c both say "int magic_number = 20;" inside them; that is, they effectively both define magic_number.

You are only allowed to have one definition of something. It's declarations you are allowed to have more then one of. A declaration, would be something like foo.c saying "int magic_number = 20;" (definition) and bar.c saying "extern int magic_number;" (declaration). Any extra files would use that declaration.

what you probably want to be doing in the header file is '#define TITLE_FILE "title.cdb" '(with no semicolons). This tells the preprocessor, which runs through your code before everything else, "any time you see the string TITLE_FILE in my code and you're looking for identifiers, have a cookie"... um... not quite.

Actually it says "any time you see the string TITLE_FILE in my code and you're looking for identifiers, replace the string TITLE_FILE with the string literal "title.cdb"

Because you're not defining a variable, you're not going to get any lip from the compiler about redefining a variable.
Posted by KaGez on 20:52:00 10-09-2002
put this in the beginning of each header file you write yourself:

#IFNDEF __H_
#DEFINE __H_

/* code block */

#ENDIF

These things are called "Header Guards" (or something simmilar, I'm sure that it was " Guards ). As the name says, they guard you and your makefile from including the header file more than once for one .o file
[addsig]
Posted by buzgub on 21:21:00 10-10-2002
Not to be offensive or anything, but Kage-chan's solution won't fix the problem. It will just mean that, for each file compiled, the variable will be declared but once - precisely what is happening at present, in fact.
Posted by gian on 18:40:00 10-11-2002
extern is your friend!
Posted by buzgub on 12:48:00 10-13-2002
gian, not in this case. For a constant, #define makes far more sense then extern does.
Posted by KaGez on 22:28:00 10-13-2002
buzgub:
we (including me) don't know if my solution is bad or not, since we don't know the makefile this guy uses. It could fix the problem, but only if he's using a makefile I've used up to now. That may not be the case, but in many cases that solution fixed the problem, especially if the 2 files he mentioned are going to go into the same object file.
[addsig]
Posted by buzgub on 15:13:00 10-14-2002
Kagez; the question is mislabled; I'm sure it's nothing to do with the makefile.

If he did "gcc -o someprog *.c" in the relevant directory, I am certain he would get the same error.
Posted by JWalker on 08:04:00 11-15-2002
-->#IFNDEF __H_
-->#DEFINE __H_
This is invading the implementation's name space. The C standard specifies that identifiers beginning with two and underscore followed by a lower case letter or another underscore are reserved for use by the implementation.

-->These things are called "Header Guards" (or something simmilar, I'm sure that it was " Guards ).
Inclusion guards?

-->will just mean that, for each file compiled, the variable will be declared but once
Correct.

-->precisely what is happening at present, in fact.
Incorrect. The error is multiple definitions. If the problem really is with the header file then the inclusion guards will solve it.

-JW