glib/ Header #include Style

This page is a write-up of the ideas in 609280.

This page documents how #include should be used in the .c and .h files in the glib/ directory of glib.

Source files (.c)

The following example (for an imaginary file called gfoo.c) indicates how each file should have its header include order setup. See the notes below.

/* Copyright etc...
 *
 */

#include "config.h"                 /* [1] */

#include "gfoo.h"                   /* [2] */

#include <stdio.h>                  /* [3] */
#include <string.h>

#include "gtestutils.h"             /* [4] */
#include "gslist.h"

...

Notes

  1. "config.h" needs to be included in every file and it needs to come first. See 71704 for why.

  2. Each .c file should include its corresponding .h before any other includes as a way of 'taking responsibility' for ensuring that the .h file can be #included from any context without errors (ie: the .h file does not require other .h files to come before it). Note that "config.h" still needs to be first in case "gfoo.h" includes some system header files. If there is no header file corresponding to this source file then this one can be skipped.

  3. The system header files required by this .c file.

  4. Next, the glib .h files that this module depends on. These are the individual header files included using quote marks and their basename -- never #include <glib.h> from any .c file.

Header files (.h)

Header files that will be installed by make install need to be done like this:

/* Copyright etc...
 *
 */

/* [1] */
#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
#error "Only <glib.h> can be included directly."
#endif

#ifndef __G_FOO_H__                 /* [2] */
#define __G_FOO_H__

#include <glib/gtypes.h>            /* [3] */

#include <stdarg.h>                 /* [4] */

G_BEGIN_DECLS                       /* [5] */

/* ... */

G_END_DECLS                         /* [6] */

#endif /* __G_FOO_H__ */            /* [7] */

Notes

  1. Copy/paste this right at the top of the header, under the copyright notice. It ensures that user applications don't #include individual header files. We do this because the specific location of type and symbol declarations are subject to change between versions of glib.

  2. Standard header file guards to ensure that the file is only processed once.
  3. Include additional glib headers that are required for this header to build. In this case you must use #include <glib/headername.h> style (not #include "headername.h") because the header is being included from user applications. At the very least, you will need <glib/gmacros.h>' for G_BEGIN_DECLS` but if you are including any other headers you can skip this one since it will be pulled in recursively.

  4. Include only the system headers that are needed to process the declarations in this header. It is very likely none will be required since <stddef.h> is already pulled in from gmacros.h. #include <stdarg.h> is a common exception to this rule.

  5. All function declarations must be contained between this macro and G_END_DECLS. This is required to ensure that glib works properly when used with C++ applications. It is not strictly required for typedefs or macro definitions to be contained, but you may as well do it anyway for consistency.

  6. Required to close off the section started with G_BEGIN_DECLS.

  7. Required to close off the section started with the opening #ifndef. Include the comment as a matter of style.

You should also ensure that your header is #included from glib.h.

Transitive Reduction

#include is transitive. If 'a' includes 'b' and 'b' includes 'c' then 'a' has effectively included 'c'. In this situation, we strive to have 'a' not include 'c' for itself.

For example, if your header file requires #include <glib/gtypes.h> (as most will) then you do not need to #include <glib/gmacros.h> since gtypes.h already includes that for you.

In all cases, take the transitivity of #include into account and remove any redundancy where possible. This applies both to header and source files. This will lead to slightly improved build times but more importantly it makes it less likely for entirely unneeded #include lines to remain around as code changes over time.

Projects/GTK+/BestPractices/GlibIncludes (last edited 2013-11-22 15:36:56 by WilliamJonMcCann)