473,287 Members | 3,181 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,287 software developers and data experts.

How to avoid multiple definition of a variable by multiple inclusion of a header file

Easily described problem:

Using g++ version 3.3.5 under suse 9.3,

bla.h:
-----------
#ifndef myTEST
#define myTEST
ZFSInt test;
#endif
------------

leads to an error at link time...
application.o(.bss+0x0):/path_here/application.cpp:19: multiple
definition of `test'
app.o(.bss+0x0):/path_here/app.cpp:17: first defined here
....for EVERY call of #include "bla.h"
:(

Apparently the #ifndef only works at compile time, but somehow causes
an error at linktime. Any solution? I want the variable "test"
available in all modules that #include "bla.h"

Regards,

Lars Uffmann

Aug 1 '06 #1
11 22481

<la**********@rwth-aachen.dewrote in message
news:11**********************@m79g2000cwm.googlegr oups.com...
Easily described problem:

Using g++ version 3.3.5 under suse 9.3,

bla.h:
-----------
#ifndef myTEST
#define myTEST
ZFSInt test;
#endif
------------

leads to an error at link time...
application.o(.bss+0x0):/path_here/application.cpp:19: multiple
definition of `test'
app.o(.bss+0x0):/path_here/app.cpp:17: first defined here
...for EVERY call of #include "bla.h"
:(

Apparently the #ifndef only works at compile time, but somehow causes
an error at linktime. Any solution? I want the variable "test"
available in all modules that #include "bla.h"
First, copy the definition of test above into an implementation file you'll
always link with (one which includes the header file where the definition of
ZFSInt resides). Then, preface the above declaration in blah.h with the
keyword "extern" (followed by at least one space). That tells the compiler
to look elsewhere for the actual declaration of test, allows other units to
see the variable through this header, and prevents the linker from seeing
multiple definitions.

-Howard

Aug 1 '06 #2
Howard wrote:
First, copy the definition of test above into an implementation file you'll
always link with (one which includes the header file where the definition of
ZFSInt resides). Then, preface the above declaration in blah.h with the
keyword "extern" (followed by at least one space).
Issue solved - thank you! I put the actual declaration in the cpp-file
belonging
to the blah.h class definition header file.

Any link to a website explaining this behaviour of #ifdef / #ifndef ?

Best Regards,

Lars

Aug 1 '06 #3
la**********@rwth-aachen.de wrote:
Howard wrote:
>First, copy the definition of test above into an implementation file you'll
always link with (one which includes the header file where the definition of
ZFSInt resides). Then, preface the above declaration in blah.h with the
keyword "extern" (followed by at least one space).

Issue solved - thank you! I put the actual declaration in the cpp-file
belonging
to the blah.h class definition header file.

Any link to a website explaining this behaviour of #ifdef / #ifndef ?
That's not a preprocessor issue, it's the ODR (one definition rule).
Aug 1 '06 #4
red floyd wrote:
Any link to a website explaining this behaviour of #ifdef / #ifndef ?
That's not a preprocessor issue, it's the ODR (one definition rule).
To me, that doesn't explain why
#ifndef FOO
#define FOO
class foo {
foo(){};
~foo(){};
};

int test;
#endif

successfully avoids multiple class definition but NOT multiple
declaration of the variable "test" as an integer...

I used to think #ifdef and the likes were preprocessor commands that
would completely SKIP sections of code if the condition was not met -
all the way to the next #endif.
Apparently this does not work for variable declarations - That's the
part I do not understand.

Regards,

Lars

Aug 2 '06 #5
la**********@rwth-aachen.de wrote:
red floyd wrote:
>>Any link to a website explaining this behaviour of #ifdef / #ifndef ?
That's not a preprocessor issue, it's the ODR (one definition rule).

To me, that doesn't explain why
#ifndef FOO
#define FOO
class foo {
foo(){};
~foo(){};
};

int test;
#endif

successfully avoids multiple class definition but NOT multiple
declaration of the variable "test" as an integer...

I used to think #ifdef and the likes were preprocessor commands that
would completely SKIP sections of code if the condition was not met -
all the way to the next #endif.
Apparently this does not work for variable declarations - That's the
part I do not understand.
Because you're defining a class... which is a type. No storage is
allocated. When you're declaring a variable, storage is allocated.

The other thing you need to know is that preprocessor commands don't go
across translation units.

Aug 2 '06 #6
la**********@rwth-aachen.de wrote:
red floyd wrote:
>>>Any link to a website explaining this behaviour of #ifdef / #ifndef ?

That's not a preprocessor issue, it's the ODR (one definition rule).


To me, that doesn't explain why
#ifndef FOO
#define FOO
class foo {
foo(){};
~foo(){};
};

int test;
#endif
Let's say that you include this file in two source files. What happens?
a) The class foo gets its declaration. Good, now you can create foo objects.
b) The integer test gets allocated. Once in one file and once in the second file.
Everything is fine until the link stage. The linker will try to make sense of all and will see *two* instances of int test. Which one to use? Nobody will ever be able to answer that.

The solution,

extern int test;

Goes in the header. That will tell to the compiler: There is a variable called test that is to be used, but it is only declared here. Its definition will be done somewhere else.

Then, in one of your source files, you define this variable on the normal way.
When you compile, you can refer to this variable in any source code that uses the include file, but at link time, only one instance will exist. At this point, no link error. Hooray!

I hope I was clear.

Regards,

Marco
Aug 2 '06 #7
la**********@rwth-aachen.de wrote:
Any link to a website explaining this behaviour of #ifdef / #ifndef ?
You can imagine the preprocessor is a bunch of text editor macros. Do the
substitutions by hand, or use the commands or options of your compiler that
shows the preprocessor output, and look the generated code. This result is
what the "real" compiler see.

--
Salu2
Aug 2 '06 #8
la**********@rwth-aachen.de wrote:
Easily described problem:

Using g++ version 3.3.5 under suse 9.3,

bla.h:
-----------
#ifndef myTEST
#define myTEST
ZFSInt test;
#endif
------------

leads to an error at link time...
application.o(.bss+0x0):/path_here/application.cpp:19: multiple
definition of `test'
app.o(.bss+0x0):/path_here/app.cpp:17: first defined here
...for EVERY call of #include "bla.h"
:(

Apparently the #ifndef only works at compile time, but somehow causes
an error at linktime. Any solution? I want the variable "test"
available in all modules that #include "bla.h"
Yes. You want the variable available. That means you'll need a
declaration,
not the definition. The typical variable declaration is "extern <type>
<name>;"
You put the definition in a .cpp, just like you would with function
definitions.

This has nothing to do with #ifdef, which is a preprocessor command. It
works only at compile time, and skips every second defintion of 'test'
*in
a single .cpp*, not across .cpp's. As the compiler works on single
..cpp's
it won't notice that.

HTH,
Michiel Salters

Aug 2 '06 #9
Mi*************@tomtom.com schrieb:
This has nothing to do with #ifdef, which is a preprocessor command.
It works only at compile time, and skips every second defintion of 'test'
*in a single .cpp*, not across .cpp's. As the compiler works on single
.cpp's it won't notice that.
Woohoo - I see light in the dark! Finally the explanation I've been
waiting for :) To be honest, I suspected something like this, because
the compiler creates libraries for each cpp file separately, so the
linker would spot multiple declarations of the variable, but in that
case the sense of the preprocessor commands did not occur to me - I
never realized it was only to skip further definitions within the same
cpp-File.

Thanks for clearing this up! :)
And to all the others that helped solving the problem!

Regards,

Lars

Aug 2 '06 #10
Hi,

In my implementation, it is like

#ifndef TEST
#define TEST
const char* strDescriptions[] = {"Desc1", "Desc2", "Desc3"};
#endif

How to split the definition and definition of the above.

Regds,
Chinthan EP
la**********@rwth-aachen.de wrote:
Mi*************@tomtom.com schrieb:
This has nothing to do with #ifdef, which is a preprocessor command.
It works only at compile time, and skips every second defintion of 'test'
*in a single .cpp*, not across .cpp's. As the compiler works on single
.cpp's it won't notice that.

Woohoo - I see light in the dark! Finally the explanation I've been
waiting for :) To be honest, I suspected something like this, because
the compiler creates libraries for each cpp file separately, so the
linker would spot multiple declarations of the variable, but in that
case the sense of the preprocessor commands did not occur to me - I
never realized it was only to skip further definitions within the same
cpp-File.

Thanks for clearing this up! :)
And to all the others that helped solving the problem!

Regards,

Lars
Aug 5 '06 #11
ch********@gmail.com wrote:
Hi,

In my implementation, it is like

#ifndef TEST
#define TEST
const char* strDescriptions[] = {"Desc1", "Desc2", "Desc3"};
#endif

How to split the definition and definition of the above.
First, please don't top-post on Usenet, your reply belongs below or
interleaved with the post you are replying to.

to split, declare the variable in a header and define in once and once
only in a source module.

In test.h:

extern const char* strDescriptions[];

in somefile.cc:

const char* strDescriptions[] = {"Desc1", "Desc2", "Desc3"};

--
Ian Collins.
Aug 5 '06 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Jochen Zeischka | last post by:
Hi everybody! I have a question concerning code organisation. Suppose I have the following header file: #ifndef SOME_NAME #define SOME_NAME namespace N { void F()
9
by: Mathieu Malaterre | last post by:
Hello, This thread follow my previous one on the gcc mailing list. Basically I -still- have a problem in my code. I define in a header file: static const std::string foo = "bar"; Which not...
2
by: Lu | last post by:
Hello, I am wondering how to protect a global variable in a header file from external access. So I googled and found: "The keyword 'static' has two different uses, depending on whether it is...
6
by: techBoy | last post by:
I am looking for a tool that can scan my soyrce code and check if a header file gets included more then once in a sequece of compiled code. Can some one guide me to such a tool !!
10
by: zfareed | last post by:
Similar problem to the previous post. I have created a project with about 7 files including 3 header files and 3 implementation files. I am getting a multiple definition error when compiling for...
8
by: nishit.gupta | last post by:
I was having a problem with template class memer function definition , so i serched the net and find that template class member fuction definition should be in header file else compilation will...
11
by: whirlwindkevin | last post by:
I saw a program source code in which a variable is defined in a header file and that header file is included in 2 different C files.When i compile and link the files no error is being thrown.How is...
7
by: bcpkh | last post by:
Hello All Received a header file from a supplier that defines an interface to implement but it's giving me a problem, I reproduce the general structure of the header file below; #ifndef XYZ_H...
2
by: sayeo87 | last post by:
I am having VERY weird behavior with a variable in my header file. Basically I have one .c file and one .h file where I store all definitions and prototypes. I have a "#define INFINITY 15000" macro...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: marcoviolo | last post by:
Dear all, I would like to implement on my worksheet an vlookup dynamic , that consider a change of pivot excel via win32com, from an external excel (without open it) and save the new file into a...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.