473,473 Members | 1,962 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

multiple inclusion of header file

5 New Member
Hello,

I am new to C++, coming from a background in Java and procedural languages. I am currently translating some code from Java to C++ as an exercise and have run into the following problem:

File a.h contains some constant definitions.
As a protection against multiple definitions of these constants I included the following lines at the top of it:
#ifndef const_file_def
#define const_file_def
and added at the end:
#endif

The classes defined in files b.h/b.cpp and c.h/c.cpp both need these definitions and therefore #include a.h
The class defined in files d.h/d.cpp makes use of both b and c classes, and so is compiled as follows:
c++ -o d.out d.cpp b.o c.o
where b.o and c.o were created earlier with a c++ -c command.
The problem is that despite my #ifndef clause at the top of a.h I still get a "multiple definition of " error for every constant defined in it.

How can I avoid the multiple definitions?

Many thanks,

Abe
Aug 16 '07 #1
6 12371
Banfa
9,065 Recognized Expert Moderator Expert
File a.h contains some constant definitions.
As a protection against multiple definitions of these constants I included the following lines at the top of it:
#ifndef const_file_def
#define const_file_def
and added at the end:
#endif
This is the right thing to do.

The class defined in files d.h/d.cpp makes use of both b and c classes, and so is compiled as follows:
c++ -o d.out d.cpp b.o c.o
where b.o and c.o were created earlier with a c++ -c command.
The correct format for compiling d.cpp would be

c++ -o d.out d.cpp

The compiler really has no interest in other objects, that is the relem of the linker.

The problem is that despite my #ifndef clause at the top of a.h I still get a "multiple definition of " error for every constant defined in it.
From your description I would suggest looking for a typo in the structure of you preprocessor statements in
Expand|Select|Wrap|Line Numbers
  1. #ifndef const_file_def
  2. #define const_file_def
  3.  
  4. // Definitions here
  5.  
  6. #endif
  7.  
Aug 16 '07 #2
javan
5 New Member
Many thanks. The "typo" was in fact a misunderstanding on my part: all of my constants were defined as instance variables, i.e., lacking the keyword "const". Once I introduced this keyword in front of all of them the compilation was successful because they were all inlined and referenced only once in the code.

One word about the linking: I understand that the C++ compiler as such is not interested in object files created earlier, but by default my compiler first compiles and then proceeds to link, so omitting the *.o files from the command line causes it to report a whole host of undefined references. Obviously I need the linker to run as well if I want to be able to run the resulting *.out file. Or am I again missing something?

Thanks,

Abe
Aug 16 '07 #3
Banfa
9,065 Recognized Expert Moderator Expert
One word about the linking: I understand that the C++ compiler as such is not interested in object files created earlier, but by default my compiler first compiles and then proceeds to link, so omitting the *.o files from the command line causes it to report a whole host of undefined references. Obviously I need the linker to run as well if I want to be able to run the resulting *.out file. Or am I again missing something?
Nope that sounds about right to me, many compilers proceed to run the linker as well unless you tell them not to.
Aug 16 '07 #4
weaknessforcats
9,208 Recognized Expert Moderator Expert
lacking the keyword "const". Once I introduced this keyword in front of all of them the compilation was successful because they were all inlined and referenced only once in the code.
What is happening is not what you think.

Each time a header file is included, its contents are processed. If you create variables, then each time you include the header, the variables are created again. Hence redefinition at the compiler level.

So, you do the #ifndef and the errors from the compiler go away only to be replaced by redefinition errors from the linker. This is caused by including the header file in multiple source files. The compiler sees only one file. The linker sees them all.

So, you add const and all the errors go away. Unfortunately, what does not go away are all the variables. They have still been multiply created but the const tells the linker they can only be used in the file where they were defined.

So, if you have 5000 files in your program that include this header you have 5000 sets of variables.

Solution: Do not create variables in header files.

Header files are for declarations not definitions. A declaration says a thing exists. A definition uses the declaration to create the object.

What you should do is:

In the header, declare the variables as extern. That says the variables are in another file and are sharable (external linkage). LIke this:

Expand|Select|Wrap|Line Numbers
  1. //header.h
  2. extern const int MAX;
  3. extern const in MIN;
  4.  
Then in one source file, create the variables:

Expand|Select|Wrap|Line Numbers
  1. //app.cpp
  2. extern const int MAX = 100;
  3. extern const int MIN = -100;
  4.  
Normally, constants have internal linkage so they are not sharable in other files. That is the default when you create them. The example above just overrides the default and makes the constant sharable.

Later, you can learn to not use global variables at all. However, one thing at a time.
Aug 16 '07 #5
javan
5 New Member
Many thanks for the detailed explanation. I fully agree that global variables are not a good idea - but this is not what I was trying to do. Rather, I was creating constants that are used in many places in my code. The purpose is to simplify maintenance so that if I need to I can change the value of such a constant only once and not hunt for all of its uses throughout the code. As such, I believe that defining external constants is indeed a good practice.

Thanks again,

Abe
Aug 17 '07 #6
RRick
463 Recognized Expert Contributor
Your intentions are good, but you really are placing globals throuhghout your code which results in "code bloat". In this day and age of gigabyte memory, its not that severe, but it can be avoided.

If you want global consts, then what W4cats suggests is the one of the best ways to fix the bloat. Breaking code in header and source files works for subroutines and we don't mind that.

If you don't like the extern in your header file, then put your constants in a class as static const variables. Now you don't clutter up the namespace with Min and Max variable names. You still have to separate the declaration from the defintions, but hey, that's how static class variables work.
Aug 18 '07 #7

Sign in to post your reply or Sign up for a free account.

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()
14
by: Fritz Foetzl | last post by:
I'm flummoxed. I'm a veteran C++ programmer from the Unix/Linux camp, trying to learn Visual C++. I'm trying to build a project in which I need to include one header in a couple of different files,...
1
by: mead | last post by:
This is from an article: "Given a.h and a.cpp files, a.h has been included as the first header file in a.cpp. This will make sure that a.h does not expect a certain header files to be included...
6
by: Johannes Bauer | last post by:
Hi group, I've got a question concerning inclusion of .hpp files. Currently I'm including all needed header files in the .cpp file. This means all dependencies of the package and all...
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 !!
11
by: lars.uffmann | last post by:
Easily described problem: Using g++ version 3.3.5 under suse 9.3, bla.h: ----------- #ifndef myTEST #define myTEST ZFSInt test; #endif
8
by: ewpatton | last post by:
I have a header that is shared among different CPP files for constants. When Microsoft Visual C++ links the .obj files, it complains that these names are all duplicates. How can I get it to realize...
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...
6
by: vsgdp | last post by:
I was looking at some library code today and noticed something like this: // sublibrary.h // define some constants, enums, symbols #include "componentA.h" #include "componentB.h" #include...
9
by: ramsatishv | last post by:
Hi, If I include a ".h" file for multiple times, will it increase my program size?? Regards Ram.
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

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.