Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Include guard conventions in C

What is the conventional way to set up your include guards? I usually write them as (for example.h):

#ifndef _EXAMPLE_H_
#define _EXAMPLE_H_
#include "example.h"
#endif

Does underscore convention matter? I've seen conflicting information when I googled this. Does the _EXAMPLE_H_ even have to match the name of the header?

like image 757
cjubb39 Avatar asked Jun 25 '13 21:06

cjubb39


People also ask

What is an include guard in C?

In the C and C++ programming languages, an #include guard, sometimes called a macro guard, header guard, or file guard, is a particular construct used to avoid the problem of double inclusion when dealing with the include directive.

What is the purpose of the include guard in a header file?

Include guards are used to prevent a file, actually the contents of a file, from being included more than once. The header file above has an include guard. The ifndef is an if statement. The #endif is the end of the if body.

Should you always use include guards?

Formally, you don't need include guards in your bar. h . It has a single function declaration, which can be repeated many times in one translation units. So, including this header multiple times will not lead to errors.

What is a header guard in C?

Header guard is a pattern of preprocessor directives that protect your header from being included multiple times. Header guard wraps the entire code content into an #ifndef ( #if ! defined , or another similar) block: #ifndef MY_HEADER_H #define MY_HEADER_H //... # endif.


1 Answers

Does underscore convention matter?

Yes. It matters.

Identifiers with a leading underscore followed upper case letter is reserved for implementation. So what you have would cause undefined behaviour.

The following is the C standard's specification for naming the identifiers (C11 draft):

7.1.3 Reserved identifiers

Each header declares or defines all identifiers listed in its associated subclause, and optionally declares or defines identifiers listed in its associated future library directions subclause and identifiers which are always reserved either for any use or for use as file scope identifiers.

— All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.

— All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.

— Each macro name in any of the following subclauses (including the future library directions) is reserved for use as specified if any of its associated headers is included; unless explicitly stated otherwise (see 7.1.4). — All identifiers with external linkage in any of the following subclauses (including the future library directions) and errno are always reserved for use as identifiers with external linkage.184) — Each identifier with file scope listed in any of the following subclauses (including the future library directions) is reserved for use as a macro name and as an identifier with file scope in the same name space if any of its associated headers is included.

No other identifiers are reserved. If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), or defines a reserved identifier as a macro name, the behavior is undefined.

If the program removes (with #undef) any macro definition of an identifier in the first group listed above, the behavior is undefined.

Without violating any of the above, the include guard name can be anything and doesn't have to be the name of the header file. But usually the convention I have seen/used is to use same name as that of the header file name so that it doesn't cause any unnecessary confusion.

like image 199
P.P Avatar answered Oct 02 '22 14:10

P.P