{"id":587,"date":"2019-09-15T11:53:47","date_gmt":"2019-09-15T18:53:47","guid":{"rendered":"http:\/\/35.243.195.209\/?p=587"},"modified":"2019-09-15T11:57:12","modified_gmt":"2019-09-15T18:57:12","slug":"include-guard-v-s-pragma-once","status":"publish","type":"post","link":"https:\/\/nanzhou.cc\/index.php\/2019\/09\/15\/include-guard-v-s-pragma-once\/","title":{"rendered":"Include Guard V.S. #pragma once"},"content":{"rendered":"<h2>Summary<\/h2>\n<p>In this post, I will introduce the difference between include guard and <code>#pragma<\/code> directives in C++. <\/p>\n<h2>Conclusion<\/h2>\n<p>As usual, I will present the conclusion first. <\/p>\n<ol>\n<li>Include guard is the standard way to prevent multiple inclusion of the same header; <\/li>\n<li><code>#pragma<\/code> directive is not required by C++ standard but now widely supported by most of the compilers, including GCC and clang. <\/li>\n<li>Use include guard if possible;\n<pre><code class=\"language-cpp\">\/\/ use this one\n#ifndef LIBRARY_FILENAME_H\n#define LIBRARY_FILENAME_H\n\/\/ contents of the header\n#endif \/* LIBRARY_FILENAME_H *\/<\/code><\/pre>\n<pre><code class=\"language-c++\">#pragma once\n\/\/ contents of the header<\/code><\/pre>\n<\/li>\n<\/ol>\n<h2>Details<\/h2>\n<h3>Preprocessors<\/h3>\n<p>Preprocessors are programs that process our source code before compilation and linking. There are different types of preprocessor directives: <\/p>\n<ol>\n<li>Macros;<\/li>\n<li>Include Guard;<\/li>\n<li>Conditional Compilation;<\/li>\n<li>Other directives like #pragma directives;<\/li>\n<\/ol>\n<p>The preprocessor is executed at <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/translation_phases\">translation phase 4<\/a>, before the compilation. Typically the preprocessor will first recursively replace all <code>#include<\/code>  directives with the literal file declared in the directive (usually header files, but possibly other source files); the result of this step is a preprocessing translation unit. Then it will handle <a href=\"https:\/\/en.wikipedia.org\/wiki\/Macro_expansion\">macro expansion<\/a> of <code>#define<\/code> directives, and (conditional compilation)[<a href=\"https:\/\/en.wikipedia.org\/wiki\/Object_file\">https:\/\/en.wikipedia.org\/wiki\/Object_file<\/a>] of <code>#ifdef<\/code> directives, among others; this translates the preprocessing translation unit into a translation unit.<\/p>\n<p>The files by <code>#include<\/code> directives are generally header files, which typically contain declarations of functions and classes or structs.<\/p>\n<h3>Translation Unit<\/h3>\n<p>As introduced in the above subsection, a translation unit is the output of the preprocessor. From a translation unit, the compiler generates an object file, which can be further processed and linked (possibly with other object files) to form an executable program.<\/p>\n<h3>Include Guard<\/h3>\n<p>As you may notice, the preprocessor will recursively replace all <code>#include<\/code>  directives with the literal files. There may be the case that certain classes or functions are defined twice. The resulting translation unit is invalid. See <a href=\"https:\/\/en.wikipedia.org\/wiki\/One_Definition_Rule\">One Definition Rule<\/a> for details.<\/p>\n<p><code>#include<\/code> guards prevent this erroneous construct from arising by the double inclusion mechanism.<\/p>\n<p>For example, <\/p>\n<pre><code class=\"language-c++\">\/\/File &quot;grandparent.h&quot;\n#ifndef GRANDPARENT_H\n#define GRANDPARENT_H\n\nstruct foo {\n    int member;\n};\n\n#endif \/* GRANDPARENT_H *\/<\/code><\/pre>\n<pre><code class=\"language-c++\">\/\/File &quot;parent.h&quot;\n#include &quot;grandparent.h&quot;<\/code><\/pre>\n<pre><code class=\"language-c++\">\/\/File &quot;child.c&quot;\n#include &quot;grandparent.h&quot;\n#include &quot;parent.h&quot;<\/code><\/pre>\n<p>Here, the first inclusion of &quot;grandparent.h&quot; causes the macro GRANDPARENT_H to be defined. Then, when &quot;child.c&quot; includes &quot;grandparent.h&quot; the second time, the #ifndef test returns false, and the preprocessor skips down to the #endif, thus avoiding the second definition of struct foo. The program compiles correctly. <\/p>\n<pre><code>\/\/Result\nstruct foo {\n    int member;\n};<\/code><\/pre>\n<p>In order for <code>#include<\/code> guards to work properly,  a project using must work out a coherent naming scheme for its include guards, and make sure its scheme doesn&#8217;t conflict with that of any third-party headers it uses, or with the names of any globally visible macros.<\/p>\n<h3>Pragma Once<\/h3>\n<p>If it appears in a header file, it indicates that it is only to be parsed once, even if it is (directly or indirectly) included multiple times in the same source file.<\/p>\n<p>Unlike include guards, <code>#pragma once<\/code> makes it impossible to erroneously use the same macro name in more than one file. On the other hand, since with #pragma once files are excluded based on their filesystem-level identity, this can&#8217;t protect against including a header twice if it exists in more than one location in a project (this will happen when someone copy and paste codes).<\/p>\n<p>For example, <\/p>\n<pre><code class=\"language-c++\">\/\/File &quot;grandparent.h&quot;\n#ifndef GRANDPARENT_H\n#define GRANDPARENT_H\n\nstruct foo {\n    int member;\n};\n\n#endif \/* GRANDPARENT_H *\/<\/code><\/pre>\n<pre><code class=\"language-c++\">\/\/File &quot;dir\/grandparent.h&quot;\n#ifndef GRANDPARENT_H\n#define GRANDPARENT_H\n\nstruct foo {\n    int member;\n};\n\n#endif \/* GRANDPARENT_H *\/<\/code><\/pre>\n<pre><code class=\"language-c++\">\/\/File &quot;parent.h&quot;\n#include &quot;grandparent.h&quot;<\/code><\/pre>\n<pre><code class=\"language-c++\">\/\/File &quot;child.c&quot;\n#include &quot;grandparent.h&quot;\n#include &quot;dir\/grandparent.h&quot;\n#include &quot;parent.h&quot;<\/code><\/pre>\n<p>This will work since <code>grandparent.h<\/code> and <code>dir\/grandparent.h<\/code> has the same signature <code>GRANDPARENT_H<\/code>. <\/p>\n<p>However, <\/p>\n<pre><code class=\"language-c++\">\/\/File &quot;grandparent.h&quot;\n#pragma once\nstruct foo {\n    int member;\n};<\/code><\/pre>\n<pre><code class=\"language-c++\">\/\/File &quot;dir\/grandparent.h&quot;\n#pragma once\nstruct foo {\n    int member;\n};<\/code><\/pre>\n<pre><code class=\"language-c++\">\/\/File &quot;parent.h&quot;\n#include &quot;grandparent.h&quot;<\/code><\/pre>\n<pre><code class=\"language-c++\">\/\/File &quot;child.c&quot;\n#include &quot;grandparent.h&quot;\n#include &quot;dir\/grandparent.h&quot;\n#include &quot;parent.h&quot;<\/code><\/pre>\n<p>This will violate the One Definition Rule. <\/p>\n<h2>Reference<\/h2>\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/Pragma_once\">Wikipedia Pragma Once<\/a><br \/>\n<a href=\"https:\/\/en.wikipedia.org\/wiki\/Include_guard\">Wikipedia Include Guard<\/a><br \/>\n<a href=\"https:\/\/en.cppreference.com\/w\/cpp\/preprocessor\/impl\">cppreference<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary In this post, I will introduce the difference between include guard and #pragma directives in C++. Conclusion As usual, I will present the conclusion first. Include guard is the standard way to prevent multiple inclusion of the same header; #pragma directive is not required by C++ standard but now widely supported by most of&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,5],"tags":[],"class_list":["post-587","post","type-post","status-publish","format-standard","hentry","category-c","category-proglang"],"_links":{"self":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/587","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/comments?post=587"}],"version-history":[{"count":10,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/587\/revisions"}],"predecessor-version":[{"id":598,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/587\/revisions\/598"}],"wp:attachment":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/media?parent=587"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/categories?post=587"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/tags?post=587"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}