0

This is really a philosophical question. I could really use the above type of preprocessor statement. If I've #included a file/header/etc in the first program file, I shouldn't have to include that same file in other files, I believe.

I've looked at the #ifdef and #ifndef statments, but these seem geared more towards constants than for #includes (which, I don't think will work).

I've seen something like this in C++:

#include <cstdlib>
#include <iostream>
#include <string>


#ifndef HASH_H
#define HASH_H

Yet, I don't understand how it works, or if it's also useful in C.

Dave
  • 11
  • 5
  • 3
    The `#ifndef` pattern is quite common across both C and C++. There's also [`#pragma once`](https://en.wikipedia.org/wiki/Pragma_once) if your compiler supports it. – tadman Aug 11 '20 at 22:59
  • 1
    Related to the header guards: [https://stackoverflow.com/questions/8020113/c-include-guards](https://stackoverflow.com/questions/8020113/c-include-guards) – drescherjm Aug 11 '20 at 23:01
  • Many header files wrap all the content inside a #ifndef. Or they use a #pragma once. See: https://stackoverflow.com/questions/787533/is-pragma-once-a-safe-include-guard – Andrew Truckle Aug 11 '20 at 23:01
  • 1
    Common convention is to use header guards. If your project is named Fuzzle, and your header file is name Bear.h (in the Fuzzle/Bear.h location), you'd put in `#ifndef FUZZLE_BEAR_H` at the top, and then `#define FUZZLE_BEAR_H` as the next line, then the rest of the file, followed by `#endif` at the very end. – Eljay Aug 11 '20 at 23:02
  • 1
    Re “If I've #included a file/header/etc in the first program file, I shouldn't have to include that same file in other files, I believe”: If you mean that something included in one source file (for C, these are typically files whose names end in `.c`) does not have to be included in other, separately compiled source files, that is not correct. Each source file should include all headers that declare identifiers or macros that the source file uses. – Eric Postpischil Aug 11 '20 at 23:41
  • Consider trying the "-H" compiler option to g++. Unfortunately, even my 11 line HelloWorld.cc pulls in 225+ includes. The good news is that the output (of includes) have full paths. The bad news is how many. I once use std::map to collect this set of file names. Here, the unique files will have a count of 1. And you should be able to identify your own include files (separate from sys library) based on the path. Based on path, I can easily see that my HelloWorld.cc used only library files, as all the paths started with "/usr". – 2785528 Aug 12 '20 at 00:39
  • Thanks, y'all. These are all a good help. Thanks, Eric, I've never written C any other way, but didn't really know why. #pragma once would probably be my choice in C++. – Dave Aug 12 '20 at 23:00

1 Answers1

3

How to check for an already #include file

By defining a macro in the file, and then checking before that definition whether that macro has already been defined, and if it is, then remove the entire content of the header. Example:

// check if macro is defined
#ifndef SOME_UNIQUE_MACRO
// define the macro
#define SOME_UNIQUE_MACRO

// content of the header is included at most once

#endif

This idiom is called an include guard.


This strategy fails if the chosen macro is defined or undefined for any other reason within the translation unit. Name conflicts are a common problem with pre-processor macros. Thus, careful consideration must be taken to ensure that the name is unique.

The problem of uniqueness can be solved by using #pragma once declaration instead of the macro definition. This is not standard C++, but it is supported by all major compilers.

eerorika
  • 232,697
  • 12
  • 197
  • 326