見出し画像

C言語-#14.インクルードガード

はおはお。

「インクルードガード」とは簡単に言っちゃうと同じソースで同じヘッダを何回も呼ばないようにする仕組み(読んじゃって多重定義になったりするのを防ぐ)です。

上記記事の宣言もそんな感じに使用するもので基本的にすべてのソースに読ませるのですが、いちいち #include~ って書くのも煩わしいため 核となるヘッダから Includeすることが多いです。そういう時に有効なわけですね。


書き方

書き方としては簡単で、

#ifndef INCLUDE_GURAD
#define INCLUDE_GURAD
 
#include <types.h>
#include "my_config.h"
 
#endif //INCLUDE_GURAD

このように INCLUDE_GURAD が #ifndef の時だけ以下が読まれすぐに #define します。こうすることで同じスコープのファイルでの再読み込みを抑止できるわけです。

pragma once ディレクティブ

最近のコンパイラでは #pragma once が使用できることが多いです。C言語では C99規格以降、gccでは Ver.3.4以上で使用できます。実装はコンパイラに依存するので確認してから使いましょう。

で、pragma once とは?

先頭行に書くだけで同じファイルの読み込みを抑止してくれる簡単で大変便利なものです。書き方も

#pragma once
 
#include <types.h>
#include "my_config.h"

と一行追加するだけです。古い形でサンドイッチにしていたようなことはしなくていいので見通しもよくなります。

デメリット

「依存関係を意識しないで Includeする癖がついてしまう」ことが挙げられます。多重 Includeを回避するために使用するのはいいですが、そもそも ヘッダからヘッダを Includeすることは一部例外を除いては しないほうが賢明です。

例えば menu_A.hmenu_B.hmenu.h から Includeした時、各ソースから menu.h をIncludeした場合 menu_A.h を変更すると menu_B.c も再コンパイルされてしまうといった具合です。

/*
 * menu.h
 */
@pragma once

#include "menu_A.h"
#include "menu_B.h"
/*
 * menu_A.c
 */
#include "menu.h"
/*
 * menu_B.c
 */
#include "menu.h"

おわり

楽しようぜぃ~っ!

悉く書を信ずれば則ち書無きに如かず