Solved

multiple inclusion

Posted on 2003-11-08
3
161 Views
Last Modified: 2010-05-18


As with most things mine is a matter of confusion.  So after getting some assistance on understanding name mangling and mixing C with C++, I have a question on multiple inclusion this after some reading.

take the case file_a.h

// file_a.h
#ifndef  FILE_A_H
#define FILE_A_H

  int idx;
  int jdx;

#endif

// file_a.cpp             // source file for file_a
#include "file_a.h"

// file_b.h                 // header file for file_b
#include "file_b.h"

both file_a and file_b are compiled with makefile or ..
In theory the ONLY thing the inclusion guard prevents me against is the potential problem of including file_a.h more that once in a single translation unit.

In other words
// file_b.h                 // header file for file_b
#include "file_b.h"
#include "file_b.h"     // inclusion guard kicks in ..... here

The inclusion guard does nothing to prevent idx and jdx from being defined ONCE for each header file that includes file_a.h hence the need for the extern.  

My assessment correct?

I suspect the extern is the ONLY way around this .. even if i created a common header

For instance

// common_header.h
#ifndef COMMON_HEADER_H
#define COMMON_HEADER_H

  int idx;
  int jdx;

#endif


// file_a.h
#include  "common_header.h"

// file_b.h
#include "common_header.h"

// file_c.h
#include "common_header.h"

Welcome extern again as the solution to this multiple inclusion problem?

Now my confusion.  Why does the compiler not complain if I had a struct or function prototype in my common_header file?

// common_header.h
#ifndef COMMON_HEADER_H
#define COMMON_HEADER_H

  int idx;   // doesnt like these
  int jdx;   // doesnt like these

  struct MYSTRUCT   // likes these
  {
     int abc   :  4;
     int def   :  16;  
  }
  void DoSomethingSilly ();

#endif

Finally in a ++ enviornment it's my understanding that the only solution - besides preprocessortricks - around defining variables with external linkage (globals) in header files and including those header files in multiple translation units is to avoid defining variables with external linkage in header files.
The question then becomes, if I have a variable I'd like to reference in two different translation units how can I avoid defining it in a header with extern?

 
0
Comment
Question by:forums_mp
3 Comments
 
LVL 19

Expert Comment

by:Dexstar
Comment Utility
forums_mp:

The proper thing to do is declare the variable with "extern" in your header file, and then in one (usually the corresponding one) of your .cpp files, you declare the variable.  The header is the declaration, and the .cpp is the instantiation.  That will allow any module that includes the .h file to access that variable.

The reason function prototypes don't give you an error about multiple inclusion is because you are just defining them, you're not declaring them.  There is a difference.


Hope that helps,
Dex*
0
 
LVL 15

Accepted Solution

by:
efn earned 50 total points
Comment Utility
> The inclusion guard does nothing to prevent idx and jdx from being defined ONCE for each header file that includes file_a.h hence the need for the extern.  

> My assessment correct?

Yes.

> Welcome extern again as the solution to this multiple inclusion problem?

Yes.

> Why does the compiler not complain if I had a struct or function prototype in my common_header file?

A declaration says something exists somewhere, e.g.

extern int idx;

When the compiler sees this, it just generates an unresolved reference, which the linker later resolves if it can.

A definition allocates some storage and gives it a name, e.g.:

int idx;

You might be interested in this FAQ answer from the comp.lang.c FAQ:

http://www.lysator.liu.se/c/c-faq/c-10.html#10-7

A structure declaration by itself just declares the structure type.  It doesn't say that any object of that type exists anywhere.  Since not even one object is defined by this declaration, there is no problem with multiple definitions.

Similarly, there is a difference between the declaration and the definition of a function.  The definition is the one with a function body in braces.  What you showed is only a declaration:  it says that the function has a body somewhere else, but it doesn't define the function, so again, there is no problem with multiple definitions.

> The question then becomes, if I have a variable I'd like to reference in two different translation units how can I avoid defining it in a header with extern?

You can define it in one file and declare it in another file without using a header file.  For example:

file_a.cpp:

int idx;

file_b.cpp:

extern int idx;

More importantly, why do you care?  What's your objection to the standard approach?

By the way, it's better to design without global variables anyway.

--efn
0
 
LVL 9

Expert Comment

by:tinchos
Comment Utility
No comment has been added lately, so it's time to clean up this TA.
I will leave the following recommendation for this question in the Cleanup topic area:

Split: Dexstar {http:#9707424} & efn {http:#9708063}

Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Tinchos
EE Cleanup Volunteer
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now