きくらげ観察日記

好きなことを、適当に。

さよならインクルードガード

タイトルは嘘です。

ある程度経験のあるCプログラマーなら、

#ifndef HOGEHOGE_H
#define HOGEHOGE_H

....

#endif /* HOGEHOGE_H */

といった定型文をおそらく数百回は書いたことがあるでしょう。
これらを省略するため[要出典]に、#pragma onceというディレクティブが各処理系により提供されています。#pragma onceが書かれたファイルを処理系が見つけた場合、処理系はそのファイルと同じファイルを2回以上読み込むことはありません。
このディレクティブを利用することによって、この無駄に長い三行を省略することができるようになります。

以下の記事のように、強硬派の人たちはすでに#ifndefによるインクルードガードを「してはいけません」とまで言っています。
postd.cc

しかし、ほぼ事実上の標準とは言え、言語仕様にない機能をほいほい使ってしまっていいものなのでしょうか?

また、そもそもの「同じファイル」というのは何かという問題もあります。通常は同じパスをもつファイルを同一のものとみなせば事足りるかもしれませんが、シンボリックリンクやハードリンクが貼ってあった場合、それらと元ファイルも同一であると考えるほうが自然です。しかし、そういった同一性を調べる方法は環境依存のものしかなく、しかも場合によってはその判定が行えない場合もあります。

#pragma once versus #ifndef - C++ Forum

上のサイトにはファイルの同一性判定ができない状況の実例が書かれています。SMBは使ったことがないので詳しくはわかりませんが、SMB上ではinodeのようなファイルの同一性を判定する方法が存在しないようです。

上のような状況になることはまずないとは思いますが、どんな状況でも確実に動く手段ではない以上、#pragma onceを使うのは危険なのではないでしょうか……?

というわけで、僕はこれからも#ifndefを使い続けます。