Which of the following is a directive used to prevent a header file from accidentally being included more than once?

ID: cpp/duplicate-include-guard
Kind: problem
Severity: error
Precision: high
Tags:
   - reliability
   - maintainability
   - modularity
Query suites:
   - cpp-security-and-quality.qls

Click to see the query in the CodeQL repository

A common pattern in header files is to use pre-processor directives to guard a header file against being processed more than once per translation unit. This practice is intended to prevent compilation errors. However, pre-processor include guards are prone to human error themselves because each include guard must be assigned a unique macro name to function correctly. If two header files share the same guard macro, the compiler may unexpectedly skip the second file it encounters, leading to compilation errors or configuration bugs.

The query will flag the pre-processor #ifndef directive at the beginning of any include guard that matches another include guard in the project. Browsing the list of results you will be able to find the other directive(s) which use the same macro.

Recommendation¶

First decide whether the duplicate include guard is dangerous. A duplicate include guard may cause the header file to be skipped over when it shouldn’t be, but occasionally this design is used on purpose to ‘override’ an existing header file.

To address the issue, rename the macros used by all but one instance of the duplicate include guard. Remember to change both the #ifndef and the #define directive to use the new macro name. Alternatively, consider using the #pragma once directive to prevent multiple inclusion without the need to define unique macros.

Example¶

Here’s an example of two header files that have accidentally been given the same include guard macro. To fix the issue, rename both occurrences of the macro in the second file, for example to ANOTHER_HEADER_FILE_H.

// header_file.h

#ifndef HEADER_FILE_H
#define HEADER_FILE_H

	// ...

#endif // HEADER_FILE_H

// another_header_file.h

#ifndef HEADER_FILE_H // should be ANOTHER_HEADER_FILE_H
#define HEADER_FILE_H // should be ANOTHER_HEADER_FILE_H

	// ...

#endif // HEADER_FILE_H

References¶

  • Wikipedia: Include guard

  • © GitHub, Inc.
  • Terms
  • Privacy


2.4 Once-Only Headers

If a header file happens to be included twice, the compiler will process its contents twice. This is very likely to cause an error, e.g. when the compiler sees the same structure definition twice. Even if it does not, it will certainly waste time.

The standard way to prevent this is to enclose the entire real contents of the file in a conditional, like this:

/* File foo.  */
#ifndef FILE_FOO_SEEN
#define FILE_FOO_SEEN

the entire file

#endif /* !FILE_FOO_SEEN */

This construct is commonly known as a wrapper #ifndef. When the header is included again, the conditional will be false, because FILE_FOO_SEEN is defined. The preprocessor will skip over the entire contents of the file, and the compiler will not see it twice.

CPP optimizes even further. It remembers when a header file has a wrapper ‘#ifndef’. If a subsequent ‘#include’ specifies that header, and the macro in the ‘#ifndef’ is still defined, it does not bother to rescan the file at all.

You can put comments outside the wrapper. They will not interfere with this optimization.

The macro FILE_FOO_SEEN is called the controlling macro or guard macro. In a user header file, the macro name should not begin with ‘_’. In a system header file, it should begin with ‘__’ to avoid conflicts with user programs. In any kind of header file, the macro name should contain the name of the file and some additional text, to avoid conflicts with other header files.


Content

  • 1 Objective
  • 2 Background
  • 3 Scenario
  • 4 Method
    • 4.1 
  • 5 Further Reading

Tested on

Debian (Etch, Lenny, Squeeze)
Ubuntu (Lucid, Maverick, Natty, Trusty)

Objective

To prevent a C or C++ header file from being compiled more than once as part of any given compilation unit, regardless of how many times it is included by other files

Background

Within a C or C++ program there are some types of declaration that cannot be safely repeated within a given compilation unit. These include class, struct, union, enum and function declarations (except for incomplete ones) and typedefs (in C but not in C++).

This can be problematic when header files include other header files, and doubly so when they are part of a library intended for use by other programmers.

(A compilation unit typically consists of one source file, and all of the header files that are directly or indirectly included by that source file.)

Scenario

Suppose that you are writing a library in C++ called libfoobar which provides a number of header files. Three of these are named foo.h, bar.h and baz.h. The files foo.h and bar.h both include baz.h.

The file qux.cc is part of a program that uses libfoobar. It includes both foo.h and bar.h. In the absence of any preventative measures, compiling qux.cc would cause baz.h to be compiled twice. This is an error because baz.h contains a class declaration. You wish to prevent this or any similar errors from occurring.

Method

The standard method for preventing a header file from being compiled more than once is to add an include guard. This consists of:

  • a #define directive, which sets a macro when the header is compiled to indicate that it should not be compiled again, and
  • an #ifndef directive, which prevents the header from being compiled if the macro has already been defined.

For example, using the include guard macro name LIBFOOBAR_BAZ for the file baz.h:

#ifndef LIBFOOBAR_BAZ
#define LIBFOOBAR_BAZ

class baz
{
    // ...
};

#endif

The chosen macro name must be unique within the program in question. In the case of libraries the aim should be to make it globally unique, so that indepenently developed libraries can be used alongside each other without interference. To this end it is helpful to use a systematic naming convention for the include guard macros. Typically this would incorporate the name of the program or library, and the relative pathname of the header file in question (as in the example above).

If you examine the system headers in /usr/include then you may encounter include guard macro names that begin with an underscore. For example, the header file <stdlib.h> from the GNU C Library uses the name _STDLIB_H for its include guard. Do not mimic this convention: those names are reserved for use by the compiler and standard library, and using them for other any purpose results in undefined behaviour. The specific macro names to avoid are those that begin with:

  • a double underscore, or
  • an underscore followed by an upper case letter.

It is considered good practice to add include guards to all header files, whether or not they are technically needed. This avoids the need to determine which guards are necessary, eliminates the possibility of making a mistake, and ensures that the code is robust against future changes.

Further Reading

  • Brian W Kernighan and Dennis M Ritchie, The C Programming Language (2nd ed.), ISBN 0-13-110362-8, 1988, pp91-92
  • Bjarne Stroustrup, The C++ Programming Language (special ed.), ISBN 0-201-70073-5, AT&T, 2000, p216

Is a member function that is automatically called when a class object is?

A destructor is a member function that is invoked automatically when the object goes out of scope or is explicitly destroyed by a call to delete . A destructor has the same name as the class, preceded by a tilde ( ~ ).

Which function is automatically called in C plus plus if we do not define it in the class?

A constructor in C++ is a special method that is automatically called when an object of a class is created.

Which of the following is automatically called when an object is destroyed?

A destructor is a member of a function which is automatically called when the class is destroyed.

Which operator can be used by an object to access members of the class?

Accessing the members of the class (data and functions) is done using the dot (.) operator, which is also called as the member access operator. If obj is the name of the object and there is a function “display ()” in the class, then the function can be accessed as “obj. display ()”.