C++勉強記録(江添亮のC++入門) - 001
__has_include()について
江添亮のC++入門にて下記コードの意味を調べたのでメモを残す。
# if __has_include(<string_view>)
# include <string_view>
# endif
__has_includeとは下記のような機能である。
__has_includeはインクルードするファイルが存在するかどうかを返す述語である。
__has_includeに指定されたインクルードファイルが存在する場合は 1 として評価され、インクルードファイルが存在しない場合は 0 として評価される。
つまり問題となるコードは、<string_view>というヘッダが存在するかどうかを確認し、存在すればインクルードするというコードなのである。
ちなみに、__has_include()が使用できるのはc++17以降である。
#warningについて
ついでに、参照:cpprefjp - C++日本語リファレンスの__has_includeの説明ページに載っていた下記の例コードについても調べた。
# if __has_include(<has_include.hpp>)
# warning <has_include.hpp> is found
# else
# warning <has_include.hpp> is not found
# endif
上記コードを参考に下記のようなプログラムを作成した。
has_include.h
# include <iostream>
# if __has_include(<string_view>)
#include <string_view>
#warning <string_view> is found
# else
#warning <string_view> is not found
# endif
has_include.cpp
# include "has_include.h"
int main() {
}
実行結果:
$ g++ -std=c++20 -o has_include ./has_include.cpp
In file included from ./has_include.cpp:1:
./has_include.h:5:3: warning: #warning <string_view> is found [-Wcpp]
5 | #warning <string_view> is found
| ^~~~~~~
上記実行結果のように、コンパイル時にwarning messageが出力された。
#warning ディレクティブ(#warning directive)について下記サイトを参考にしました。
- 参考:SE学院
要するにコンパイラにwarningを発生させる命令であり、プリプロセッサ(preprocessor)の一部だ。
#errorディレクティブ(#error directive)も存在し、そちらはコンパイラにerrorを発生させ、エラー終了させる(コンパイルが完了しない)。
つまり問題となる例コードは、ファイルが存在するかどうかをコンパイル時にwarning message形式で出力させるコードだったのだ。
ただし、このコードには問題がある。
$ g++ -std=c++20 --pedantic-errors -o has_include ./has_include.cpp
In file included from ./has_include.cpp:1:
./has_include.h:5:3: error: #warning is a GCC extension
5 | #warning <string_view> is found
| ^~~~~~~
./has_include.h:5:3: warning: #warning <string_view> is found [-Wcpp]
上記のように、--pedantic-errors(C++の規格を厳格に守るオプション(規格に違反しているコードがコンパイルエラー扱いになる))を使用した場合コンパイルエラーとなる。
#warning is a GCC extensionとあるように、#warningはgcc/g++ の拡張であり、標準ではないという事である。
ちなみに#error directiveは言語仕様として標準化されている。