#include ガードにファイル名を入れるのは止めませんか?
#include
ガードといえば、大体こんな感じのがメジャーかと思う:
- sample.h の
#include
ガード -
#ifndef SAMPLE_H #define SAMPLE_H // 宣言・定義など #endif // ifndef SAMPLE_H
#include
ガードがあんまり好きじゃない。もちろん、
#include
ガードそのものが嫌いなわけじゃない。というか、#include
ガードは絶対に必要((#pragma once
とか #import
とかは好きだが、いかんせん、使えない環境がある以上は採用できない。))なもので、好き嫌いでどうこうする問題じゃない。嫌いなのは、#include
ガードに使われている SAMPLE_H
というマクロ名だ。#include
ガードのマクロ名は絶対に一意でなければならないからヘッダのファイル名をマクロ名に織り込むわけだが、たとえば、<some_header.h>
と <some/header.h>
の #include
ガードはどちらも SOME_HEADER_H
になってしまわないだろうか?このようなマクロ名の衝突の危険性もさることながら、もっと嫌なことがある。
#include
ガードにファイル名を織り込むと、ファイル名を変更するときに邪魔になるのだ。些細なことかもしれない。だが、ディレクトリ名を変更したりした場合の作業量は決して馬鹿にはならない*1。そして、その“面倒くささ”がリファクタリングを妨害し、プログラムは段々と理解不能な代物へと“腐敗”していく。そんなわけで、僕は、こんな感じの
#include
ガードを使っている:
#ifndef INCLUDE_GUARD_UUID_0FA2482C_F796_4715_A360_E088A24F0042 #define INCLUDE_GUARD_UUID_0FA2482C_F796_4715_A360_E088A24F0042 // 宣言・定義など #endif // ifndef INCLUDE_GUARD_UUID_0FA2482C_F796_4715_A360_E088A24F0042
何かのソースを見たときに UUID で #include
ガードの一意性を確保しているのを見て*2、パクった。uuidgen
を実行するのがちょっと面倒くさいが、まあ、大した手間じゃない。
ちなみに、some_header.h と some/header.h を区別するために #define SOME__HEADER_H
とやるのは禁じ手だ。_SOME_HEADER_H
のようにする人もたまに見かけるが、それも禁じ手:
- C++ 標準 *3 ― 17.4.3.1.2 Global names
-
Certain sets of names and function signatures are always reserved to the implementation:
- Each name that contains a double underscore (
__
) or begins with an underscore followed by an upper-case letter (2.11) is reserved to the implementation for any use. - Each name that begins with an underscore is reserved to the implementation for use as a name in the
global namespace.
- Each name that contains a double underscore (