Reputation: 96984
I have the following "constants" header:
/* constants.h */
#ifdef __cplusplus
extern "C" {
#endif
#pragma once
#ifndef CONSTANTS_H
#define CONSTANTS_H
const char * kFoo = "foo";
const char * kBar = "bar";
#endif
#ifdef __cplusplus
}
#endif
I am #include
-ing this header in files X.c
and Y.c
.
Note that I am not including this in X.h
or Y.h
.
The files X.c
and Y.c
get compiled into object files which are archived into a static library called libXY.a
.
When I include X.h
and Y.h
in Z.h
, and when I link to libXY.a
, I cannot compile Z.c
without errors:
/* Z.h */
#include "X.h"
#include "Y.h"
I get the following compilation errors when trying to compile Z.c
:
/path/to/libXY.a(X.o):(.data+0x0): multiple definition of `kFoo`
/path/to/libXY.a(Y.o):(.data+0x0): first defined here
/path/to/libXY.a(X.o):(.data+0x8): multiple definition of `kBar`
/path/to/libXY.a(Y.o):(.data+0x8): first defined here
I have tried setting kFoo
and kBar
to extern
, but that does not help.
How would I resolve multiple definitions, when I am only including the constants once (via the header guard #ifndef CONSTANTS_H
)?
Upvotes: 6
Views: 8243
Reputation: 104708
How would I resolve multiple definitions, when I am only including the constants once (via the header guard #ifndef CONSTANTS_H)?
With this in constants.h
:
const char * kFoo = "foo";
a definition for kFoo
will be emitted in every translation that #include
s constants.h
. Thus, multiple definitions, which then result in link errors.
As asaelr noted (+1), you would solve it like this:
constants.h
extern const char* const kFoo;
constants.c
const char* const kFoo = "foo";
(note that i also made the pointer const, which is usually what you want to do in this case)
Upvotes: 9
Reputation: 5456
You should not define variables in header file. define them in one of the source files, and declare them (extern
) in the header file.
(You wrote "I have tried setting kFoo and kBar to extern, but that does not help." I guess that you didn't define them in a source file)
Upvotes: 4