Discussion:
duplicate symbols error for variables defined in header
(too old to reply)
TF
2003-11-26 20:01:47 UTC
Permalink
Hi,
I have a very basic question. I have defined few constants (const char
*) in a header file (unix C) that i want to use in some library files
as well as a main (executable) file (this file also uses that library
functions). While linking compiler gives "duplicate symbols" error.
Now I know the reason but can any one tell me how can i avoid this
proplem? Also I don't want to use 'extern' in every file for those
constants.
Thanks

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Artie Gold
2003-11-26 20:27:16 UTC
Permalink
Post by TF
Hi,
I have a very basic question. I have defined few constants (const char
*) in a header file (unix C) that i want to use in some library files
as well as a main (executable) file (this file also uses that library
functions). While linking compiler gives "duplicate symbols" error.
Now I know the reason but can any one tell me how can i avoid this
proplem? Also I don't want to use 'extern' in every file for those
constants.
Thanks
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
When using C you should *never* define variables with external
linkage in a header.

Define the variable in a single translation unit (source file) in
the library and put the extern declaration in the header.

The quick-and-dirty alternative is to make 'em `static' in the
header, giving them internal linkage.

HTH,
--ag
--
Artie Gold -- Austin, Texas
Oh, for the good old days of regular old SPAM.
j***@invalid.address
2003-11-26 20:47:50 UTC
Permalink
Post by TF
Hi,
I have a very basic question. I have defined few constants (const char
*) in a header file (unix C) that i want to use in some library files
as well as a main (executable) file (this file also uses that library
functions). While linking compiler gives "duplicate symbols" error.
Now I know the reason but can any one tell me how can i avoid this
proplem? Also I don't want to use 'extern' in every file for those
constants.
Thanks
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
When using C you should *never* define variables with external linkage
in a header.
Well you could use the preprocessor to only define it extern where it
needs to be. For example

#ifdef MAIN
# define EXTERN
# define INIT(x) = x
#else
# define EXTERN extern
# define INIT(x)
#endif

Then define MAIN in exactly one file, then you only have one place to
make changes.

Joe
Alan Balmer
2003-11-26 21:25:57 UTC
Permalink
Post by j***@invalid.address
Post by TF
Hi,
I have a very basic question. I have defined few constants (const char
*) in a header file (unix C) that i want to use in some library files
as well as a main (executable) file (this file also uses that library
functions). While linking compiler gives "duplicate symbols" error.
Now I know the reason but can any one tell me how can i avoid this
proplem? Also I don't want to use 'extern' in every file for those
constants.
Thanks
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
When using C you should *never* define variables with external linkage
in a header.
Well you could use the preprocessor to only define it extern where it
needs to be. For example
#ifdef MAIN
# define EXTERN
# define INIT(x) = x
#else
# define EXTERN extern
# define INIT(x)
#endif
Then define MAIN in exactly one file, then you only have one place to
make changes.
Joe
Not an improvement in either readability or maintainability. Artie
Gold is right - don't allocate extern storage in headers.
--
Al Balmer
Balmer Consulting
***@att.net
Måns Rullgård
2003-11-26 21:27:42 UTC
Permalink
Post by Alan Balmer
Not an improvement in either readability or maintainability. Artie
Gold is right - don't allocate extern storage in headers.
Don't define anything in headers. Headers are for declarations only.
Doing anything else will lead to trouble.
--
Måns Rullgård
***@kth.se
j***@invalid.address
2003-11-26 22:25:42 UTC
Permalink
Post by Måns Rullgård
Post by Alan Balmer
Not an improvement in either readability or maintainability. Artie
Gold is right - don't allocate extern storage in headers.
Don't define anything in headers. Headers are for declarations
only. Doing anything else will lead to trouble.
I can say from experience that this won't cause any more trouble than
having to maintain two (or more) different files when
declaring/defining globals.

How can it be more trouble to only have to change things in one place
rather than multiple places? I might be missing something, I'll
admit. what is it?

Joe
Alan Balmer
2003-11-26 22:37:57 UTC
Permalink
Post by j***@invalid.address
Post by Måns Rullgård
Post by Alan Balmer
Not an improvement in either readability or maintainability. Artie
Gold is right - don't allocate extern storage in headers.
Don't define anything in headers. Headers are for declarations
only. Doing anything else will lead to trouble.
I can say from experience that this won't cause any more trouble than
having to maintain two (or more) different files when
declaring/defining globals.
I won't try to match experience with you, I've only been programming
since 1965. However, I'll ask you to refer back to the OP's problem,
and the rather ugly kluge you suggested to get around it.
Post by j***@invalid.address
How can it be more trouble to only have to change things in one place
rather than multiple places? I might be missing something, I'll
admit. what is it?
Joe
--
Al Balmer
Balmer Consulting
***@att.net
j***@invalid.address
2003-11-26 22:54:11 UTC
Permalink
Post by Alan Balmer
Post by j***@invalid.address
Post by Måns Rullgård
Post by Alan Balmer
Not an improvement in either readability or maintainability. Artie
Gold is right - don't allocate extern storage in headers.
Don't define anything in headers. Headers are for declarations
only. Doing anything else will lead to trouble.
I can say from experience that this won't cause any more trouble than
having to maintain two (or more) different files when
declaring/defining globals.
I won't try to match experience with you, I've only been programming
since 1965. However, I'll ask you to refer back to the OP's problem,
and the rather ugly kluge you suggested to get around it.
Ok, you're a programming authority. I'll accept that. So I'll ask you
for a reason for what you say here, unless it's just a matter of style
or personal preference?
Post by Alan Balmer
Post by j***@invalid.address
How can it be more trouble to only have to change things in one
place rather than multiple places? I might be missing something,
I'll admit. what is it?
What's ugly or kludgey about that? Why is it less ugly to have to
modify two source files rather than just one?

I'm just asking.

Joe
Chuck Dillon
2003-11-28 15:51:37 UTC
Permalink
Post by j***@invalid.address
Post by j***@invalid.address
How can it be more trouble to only have to change things in one
place rather than multiple places? I might be missing something,
I'll admit. what is it?
What's ugly or kludgey about that? Why is it less ugly to have to
modify two source files rather than just one?
If you take the approach Alan suggests the problem is contained in
exactly two source files. In your approach the problem is *not*
contained in a single header file. You are relying on a compilation
token that is in a flat namespace and settable in any header or source
file and at various levels of a build system.

Over the lifetime of a code base of any significant size it will cost
you far more to manage the compiler symbols than to manage those two files.

-- ced
--
Chuck Dillon
Senior Software Engineer
NimbleGen Systems Inc.
j***@invalid.address
2003-11-26 22:23:26 UTC
Permalink
Post by Alan Balmer
Post by j***@invalid.address
Post by TF
Hi,
I have a very basic question. I have defined few constants (const char
*) in a header file (unix C) that i want to use in some library files
as well as a main (executable) file (this file also uses that library
functions). While linking compiler gives "duplicate symbols" error.
Now I know the reason but can any one tell me how can i avoid this
proplem? Also I don't want to use 'extern' in every file for those
constants.
Thanks
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
When using C you should *never* define variables with external linkage
in a header.
Well you could use the preprocessor to only define it extern where it
needs to be. For example
#ifdef MAIN
# define EXTERN
# define INIT(x) = x
#else
# define EXTERN extern
# define INIT(x)
#endif
Then define MAIN in exactly one file, then you only have one place to
make changes.
Joe
Not an improvement in either readability or maintainability. Artie
Gold is right - don't allocate extern storage in headers.
How can it not be an improvement in maintainability when you only have
to change things in one place rather than two?

Joe
Måns Rullgård
2003-11-26 22:59:30 UTC
Permalink
Post by j***@invalid.address
Post by Alan Balmer
Not an improvement in either readability or maintainability. Artie
Gold is right - don't allocate extern storage in headers.
How can it not be an improvement in maintainability when you only have
to change things in one place rather than two?
Static things only exist within one file, and should not be mentioned
outside that file. It's a bad idea to even use the same name for
static variables in different files, even though it works. It will
only create confusion.
--
Måns Rullgård
***@kth.se
j***@invalid.address
2003-11-26 23:49:50 UTC
Permalink
Post by Måns Rullgård
Post by j***@invalid.address
Post by Alan Balmer
Not an improvement in either readability or maintainability. Artie
Gold is right - don't allocate extern storage in headers.
How can it not be an improvement in maintainability when you only have
to change things in one place rather than two?
Static things only exist within one file, and should not be mentioned
outside that file. It's a bad idea to even use the same name for
static variables in different files, even though it works. It will
only create confusion.
Well, maybe I'm confused. The OP said

"I have a very basic question. I have defined few constants (const
char *) in a header file (unix C) that i want to use in some
library files as well as a main (executable) file (this file also
uses that library functions). While linking compiler gives
"duplicate symbols" error. Now I know the reason but can any one
tell me how can i avoid this proplem? Also I don't want to use
'extern' in every file for those constants."

Which doesn't sound to me like he's declaring anything static. In C++
using const gives static linkage, but not in C.

It looks to me that he wants to share these variables between the main
program and the libraries, which is not what you normally do with
static variables.

If that's right, wouldn't he have to declare the same const char *
with the same value as static in every file he needed it in? Then if
he needed to change its value he'd have to change every one of those
files.

Joe
Måns Rullgård
2003-11-27 00:48:53 UTC
Permalink
Post by j***@invalid.address
Post by Måns Rullgård
Post by j***@invalid.address
Post by Alan Balmer
Not an improvement in either readability or maintainability. Artie
Gold is right - don't allocate extern storage in headers.
How can it not be an improvement in maintainability when you only have
to change things in one place rather than two?
Static things only exist within one file, and should not be mentioned
outside that file. It's a bad idea to even use the same name for
static variables in different files, even though it works. It will
only create confusion.
Well, maybe I'm confused. The OP said
"I have a very basic question. I have defined few constants (const
char *) in a header file (unix C) that i want to use in some
library files as well as a main (executable) file (this file also
uses that library functions). While linking compiler gives
"duplicate symbols" error. Now I know the reason but can any one
tell me how can i avoid this proplem? Also I don't want to use
'extern' in every file for those constants."
Which doesn't sound to me like he's declaring anything static. In C++
using const gives static linkage, but not in C.
It looks to me that he wants to share these variables between the main
program and the libraries, which is not what you normally do with
static variables.
That's what I thought first, but then he said he didn't want to use
extern. This being a bit unusual, I tried to make some kind of sense
out of it, and made some erroneous conclusions.
Post by j***@invalid.address
If that's right, wouldn't he have to declare the same const char *
with the same value as static in every file he needed it in? Then if
he needed to change its value he'd have to change every one of those
files.
The C way to do that is to declare the variable as 'extern const char *'
in the header file and define it as 'const char *foo = "bar"' in one
of the C files. That way the value is only given in one place. The
alternative is to use preprocessor macros, and I don't see anything
bad with that.
--
Måns Rullgård
***@kth.se
Måns Rullgård
2003-11-27 09:31:23 UTC
Permalink
Post by TF
I have a very basic question. I have defined few constants (const char
*) in a header file (unix C) that i want to use in some library files
as well as a main (executable) file (this file also uses that library
functions). While linking compiler gives "duplicate symbols" error.
Now I know the reason but can any one tell me how can i avoid this
proplem? Also I don't want to use 'extern' in every file for those
constants.
Declare the variable as extern in the header file, and without extern
in one of the source files. There's no other way to do it. You do
want the variable to be shared in all the files, right? Otherwise,
just declare it static in all the files, and each file will have it's
own copy.
--
Måns Rullgård
***@kth.se

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Daniel Krügler (nee Spangenberg)
2003-11-28 08:59:28 UTC
Permalink
Hello, TF,
Post by TF
Hi,
I have a very basic question. I have defined few constants (const char
*) in a header file (unix C) that i want to use in some library files
as well as a main (executable) file (this file also uses that library
functions). While linking compiler gives "duplicate symbols" error.
Now I know the reason but can any one tell me how can i avoid this
proplem? Also I don't want to use 'extern' in every file for those
constants.
Thanks
Two possible solutions come to my mind:

- Encapsulate the given constant string in an unnamed namespace. This
will provide external linkage (for the pointer), but provide unique
constants
for every translation unit.

- Change the declaration of the constants from
const char* myString = ...;

to

const char * const myString = ...;

This will make the linkage of the string constants internal, which might
have
disadvantages in case of some programming techniques (like instantiation
of
template)

Hope that helps,

Daniel





[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Francis Glassborow
2003-11-29 16:58:36 UTC
Permalink
In article <***@bdal.de>, Daniel KrÃŒgler <***@bdal.de>
writes
Post by Daniel Krügler (nee Spangenberg)
Hello, TF,
Post by TF
Hi,
I have a very basic question. I have defined few constants (const char
*) in a header file (unix C) that i want to use in some library files
as well as a main (executable) file (this file also uses that library
functions). While linking compiler gives "duplicate symbols" error.
Now I know the reason but can any one tell me how can i avoid this
proplem? Also I don't want to use 'extern' in every file for those
constants.
Thanks
- Encapsulate the given constant string in an unnamed namespace. This
will provide external linkage (for the pointer), but provide unique
constants
for every translation unit.
True, but it will also ensure a unique instantiation per TU if you use
the addresses in a template.
--
Francis Glassborow ACCU
If you are not using up-to-date virus protection you should not be reading
this. Viruses do not just hurt the infected but the whole community.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Continue reading on narkive:
Search results for 'duplicate symbols error for variables defined in header' (Questions and Answers)
3
replies
Avoiding multiple definition errors in C++?
started 2008-04-07 17:31:53 UTC
programming & design
Loading...