473,734 Members | 2,788 Online
Bytes | Software Development & Data Engineering Community
+ 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 12389
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 misunderstandin g 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
21078
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
1772
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, but the classic multiple inclusion problem is biting me hard. The #ifndef..#define..#endif method doesn't seem to be working, although all the documentation I've read indicates that it should. As a small example, I have an empty console...
1
1429
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 before a.h. As a.h has been included as the first file, successful compilation of a.cpp will ensure that a.h does not expect any other header file to be included before a.h. If this is followed for all classes, (i.e. x.cpp always includes x.h as...
6
1751
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 dependencies of these dependencies and so on. This is quite ugly. A start of an "Example.cpp" file could look like this
6
5205
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
22572
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
4806
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 that these are coming from the same header and refer to the same things instead of making two different copies?
10
2812
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 one specific file of class. I have checked that if there is more than one allocation of storage for identifiers, this error arises. But I don't see where the problem lies. Any suggestions? <code> //ItemType.h #ifndef ItemType_hpp // I was...
6
2609
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 "componentC.h"
9
1727
by: ramsatishv | last post by:
Hi, If I include a ".h" file for multiple times, will it increase my program size?? Regards Ram.
0
8776
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9449
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9310
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9182
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8186
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
4550
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 last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4809
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2724
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2180
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.