オプション沼(15) インクルードガードの闇?-Wno-import、#importは非推奨

Joseph Halfmoon

遥か太古の時代、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拡張が文法チェックしたところでは。)import_example_c

しかし、上記のコードはビルド可能。こんな感じ。noW_warn

warningは出てますが、気にせず実行すれば、実行に支障なし。Wnoimport_exec

まあ、warning出るのは気持ちが悪いので、-Wno-import オプションを付加して警告を抑止しようと試みます。Wnoimport_warn

あれあれ警告でるじゃん。そこで我に返って警告文を見れば、deprecatedとな。つまり、#importだから、という警告ではなく「非推奨」扱いの警告みたいです。

以下のように -Wno-deprecated と非推奨警告を抑止させてみると警告消えました。noW_warn_noW_Deprecated

それどころか、-Wn-deprecatedのみで-Wno-import無でも警告消えます。

-Wno-import オプション意味なし(テストしたgccバージョンでは。)どこかのバージョンで大人の事情が入ったのか?

オプション沼(14) 最適化で以下省略なコード書いてみました。gcc -O3オプション へ戻る

オプション沼(16) ANSI-C(ISO-C)の闇? -ansiと-pedantic へ戻る