Why not multiple inclusion of a header file if certain precautions are taken?

In summary, the conversation discusses the topic of multiple inclusion of a header file in C programming. The experts suggest that it should be avoided to prevent conflicts and errors, and provide examples of how it can cause issues with struct, enum, and typedef declarations. They also mention the use of #ifndef and #define to prevent multiple inclusion.
  • #1
Eus
94
0
Hi Ho!

I often heard people say that we should avoid multiple inclusion of a header file.
And, they very often show how to do it.
But, I myself haven't yet found the reason of not to do it when certain precautions are taken.

What I am going to discuss here is C programming, not C++.

I included one single header file containing:
- function prototype
- struct declaration
- enum declaration
- typedef
multiple times in several source code files, but my gcc happily compiled the source code files.

Of course, if I added one variable definition within the header file (e.g. int x = 0), gcc complained of multiple variable declarations.

But, I know that a variable should be best defined in a source code file not in a header file.

Therefore, as far as I don't put any variable definition in a header file, there is no problem with the multiple inclusion of the header file, isn't there?

Is there any reason to say that multiple inclusion of a header file should be avoided at all?

What do you think?

Thank you.


Eus
 
Technology news on Phys.org
  • #2
I think, the c preprocessor takes the last definition of a meta variable.
 
  • #3
The standard C library header files - like stdlib.h - look like this, simplfied a LOT:
Code:
#ifndef __STDLIB__
#define __STDLIB__
stdlib stuff goes in here
...
...
#endif /* __STDLIB__ */
This prevents the header from causing duplicate symbol errors, etc because if the preproccesor tries to include stdlib.h a second time, 99.5% of it is skipped over.
You can read your header files and see how this is implemented for your compiler.

None of the include "defines" like __STDLIB__ are defined anywhere else. Don't you do it either.

If you need to use a macro directive like _INCLUDE_POSIX_SOURCE to have a proper global effect, it has to appear in your code before any include whatsoever.
 
  • #4
Also, because of the information above, what do you think you will you accomplish by including STDC header files more than one time? All bets are off on homegrown header files that do not follow the above convention.
 
  • #5
Eus said:
Is there any reason to say that multiple inclusion of a header file should be avoided at all?
Suppose you have some header file foo.h that defines a structure and prototypes a function that uses the structure. A source file that includes foo.h twice as follows will fail to compile:
Code:
#include "foo.h"
#include "foo.h"
void foo (struct foo * foo_ptr)
{
   ...
}

This, on the other hand, will compile:
Code:
#include "foo.h"
void foo (struct foo * foo_ptr)
{
#include "foo.h"
   ...
}

The difference is in scope. It is perfectly valid in C to use the same name in different scopes. The first #include occurs at file scope, while the second occurs in function scope. Note well: While it is valid to do this, it is not very smart (exception: obfuscations such as this help in winning the IOCCC).

basePARTICLE said:
I think, the c preprocessor takes the last definition of a meta variable.
The c preprocessor is not that "smart". All that #include "foo.h" means is to replace the #include line with the body of foo.h. If the code says to do it twice, the preprocessor will do it twice. Hmm. I wonder if anyone has written a IOCCC entry that uses multiple includes in a clever way?
 
  • #6
Hi Ho!

D H said:
Suppose you have some header file foo.h that defines a structure and prototypes a function that uses the structure. A source file that includes foo.h twice as follows will fail to compile:

Ah, you are right!
Because what I did was to include a header file once in each source file (this was what I thought as multiple inclusion of a header file), I did not get any error.
But, when I included a header file two times in a single source file like what you have illustrated, I got an error.

Of course, the error is because redefinition of the struct. Whereas, multiple inclusion of a function prototype does not cause any error. Well, it is because the function prototype does not conflict each other.

Now, I have the reason to avoid multiple inclusion of a header file at all times. For example, if in a large program foo.h has been included in bar.h and main.c includes foo.h and bar.h, an error will occur if foo.h contains something (e.g., struct, enum, and typedef) other than just some function-prototypes.
Because struct, enum, and typedef declaration should be put in a header file, no precaution can be taken to make successful multiple inclusion of a header file. Therefore, multiple inclusion of a header file must be avoided at all times with
Code:
#ifndef FOO_H
#define FOO_H 1
...
#endif
construct.

So, the question has been answered.

Thank you very much.


Eus
 

1. Why is multiple inclusion of a header file a problem?

The main issue with multiple inclusion of a header file is that it can lead to duplicate declarations and definitions, causing conflicts and errors in the code. This can also result in longer compilation times and larger executable files.

2. What are some precautions that can be taken to prevent multiple inclusion of a header file?

One precaution is to use include guards, which are conditional directives that ensure a header file is only included once in a translation unit. Another option is to use the #pragma once directive, which tells the compiler to only include the header file once.

3. Can I use both include guards and #pragma once in the same header file?

Yes, it is possible to use both include guards and #pragma once in the same header file. However, it is not necessary as they serve the same purpose.

4. Are there any alternatives to using include guards or #pragma once?

Yes, another alternative is to use the #ifndef directive, which checks if a macro has been defined and only includes the header file if it has not been defined yet. This is similar to include guards but does not require the use of conditional directives.

5. Can multiple inclusion of a header file ever be beneficial?

In some cases, multiple inclusion of a header file can be useful. For example, if a header file contains only function prototypes, it can be included multiple times in different source files without causing conflicts. However, it is generally good practice to prevent multiple inclusion to avoid potential issues.

Similar threads

  • Programming and Computer Science
Replies
2
Views
373
  • Programming and Computer Science
Replies
6
Views
918
  • Programming and Computer Science
Replies
4
Views
4K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
4K
  • Programming and Computer Science
Replies
6
Views
4K
  • Programming and Computer Science
Replies
6
Views
3K
  • Programming and Computer Science
Replies
17
Views
7K
  • Programming and Computer Science
3
Replies
90
Views
11K
  • Programming and Computer Science
2
Replies
49
Views
10K
Back
Top