遥か太古の時代、C言語をかじり始めた最初からインクルードガード書いてきました。メンドクセーけど真面目にCプログラム書くときは必須。しかし書かずに済ませる方法があったです、#import。元はといえばObjective-Cの機能みたいですが、gccならフツーのCでも使えていた。知ってた?でも今はその立ち位置微妙。
※『オプション沼』投稿順indexはこちら
※動作確認に Windows11 WSL2上のUbuntu 20.04 LTS を使用しています。gccのバージョンは9.4.0です
インクルードガード
Cのヘッダファイルというものは、結構こんがらがったメンドクセー奴です。ヘッダの中でヘッダをインクルードという行為をする結果、果てしなくインクルードの連鎖が続いて分けわからなくなります。ま、ローカルで1回だけしかインクルードしないと分かっているものはいいけれど、「人気者」のヘッダとなるとどこでどれだけインクルード試みられるか分かったこっちゃありませぬ。そこで登場するのが「インクルードガード」というお作法ですな。よゐこの皆さんはお作法をまもってねと、こんな感じですかねえ。
#ifndef ヘッダファイル名_H_など #define ヘッダファイル名_H_など // ~ヘッダファイルの定義本体~ #endif
マクロ名の名づけ方にもいろいろローカルなお作法があったりしますが、要はマクロ名が定義されていたらそのヘッダは既にインクルード済ということで「#ifndef」で飛ばす仕組みです。マクロが定義されていなければ、ヘッダ本体をインクルードしますが、後々のためにそのマクロを定義しておくと。
#import
そういえば、最近真面目にCのプログラムを書いてないので、あまりインクルードガードしてません。手抜き。でもねヘッダファイルを新たに作る度にインクルードガード書かない罪悪感は感じておるのでございますよ。。。
しかしインクルードガードなど書かなくても「よきにはからって」くれる偉大なプリプロセッサ・ディレクティブがあったのです。#import とな。伝統の#include ではなく、#import とかけば後はおまかせ。ただしこれは C言語のものではありませぬ。C言語を「拡張」したObjective-C言語起源のディレクティブみたいです。わたしゃ、Objective-C無知なので知らんけど。
もともとgcc はC言語だけでなく、各種言語、その中には Objective-C も入ってます、の「コンパイラ・コレクション」であったからか、実は #include の代わりに #import と書いても受け付けてくれるのでした(ただし下の方まで読んでね。)
-Wno-import
しかし #import はCの言語仕様に含まれていないので、どうも以前のgccは、#import 使っているけど大丈夫なの?的な警告を出してたみたいです(見たわけじゃないけど。今は違う警告っす。)イチイチそんなことを言われたくない(ビルド時にログファイルが大きくなるばかりだし)よゐこのために、便利な #import を使っても警告が出ないようにするのが、このオプションのお役目だったのではなかったかと多分。推測でしかないケド。しかし既にそのお役目は失われてました。
実験のコード
実験コードは伝統のハローワールドです。伝統との唯一の違いは、#include でなく、#import と綴ったところ。以下のようにVScodeエディタ上では、エラーを示す赤色波線が表示されとります(VScode拡張が文法チェックしたところでは。)
warningは出てますが、気にせず実行すれば、実行に支障なし。
まあ、warning出るのは気持ちが悪いので、-Wno-import オプションを付加して警告を抑止しようと試みます。
あれあれ警告でるじゃん。そこで我に返って警告文を見れば、deprecatedとな。つまり、#importだから、という警告ではなく「非推奨」扱いの警告みたいです。
以下のように -Wno-deprecated と非推奨警告を抑止させてみると警告消えました。
それどころか、-Wn-deprecatedのみで-Wno-import無でも警告消えます。
-Wno-import オプション意味なし(テストしたgccバージョンでは。)どこかのバージョンで大人の事情が入ったのか?