̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ IT ニュース&コラム 2014/ 7/ 7 通巻665号 技術版 ソフトウェアデザイン館 Sage Plaisir 21  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ プリプロセッサーを行頭に書くな - リーダブル・コード(24) C言語は、プリプロセッサーで行われるコンパイルをしてから、C言語をコンパイル するという2回のコンパイルが行われます。 #include は、ほぼ必須でもあることを 踏まえると、プリプロセッサーはプログラミング言語 C言語 の一部であるといえます。 プリプロセッサーのディレクティブ(命令)か、C言語の文法かは、行頭に # が あるかどうかで簡単に識別できます。 # の左や右に空白文字やタブ文字があっても 構いません。 #include "a.h"   #include "c.h" #  include "b.h" # は行頭に書くべき、という主張があります。 もしかしたら、昔のプリプロセッサー の仕様だったのかもしれません。 現在では、そのようなプリプロセッサーはありません。 もう1つの理由は、プリプロセッサーがソースファイルの全体をどのように処理して いくかを調べるときは、行頭を見ていくだけでプリプロセッサーの部分かそれ以外の 部分かがすぐに見分けられるようにしておくと調べやすいというメリットがあること でしょう。 しかし、プリプロセッサーの開発者や検証する人でないかぎり、ソース ファイルの全体の処理結果が必要になるケースは全くありません。 それぞれの行で、 プリプロセッサーであるか C言語であるかを識別すれば十分です。 その場合、# と ディレクティブの間に空白を入れたら読みにくくなってしまいます。 その書き方は、 ユーザーのことを考えていないのです。 プリプロセッサーは C 言語と別の文法であるから、C言語のコードと混ぜると混乱 するのではないかと思っている人もいるでしょう。 #define や #if は、C言語の文法と独立しているため、次のような書き方ができます。 void func() {   num = Calc(); #define ADD 2   num += ADD; } void func() { #if VERSION >= 2   if ( num >= 20 ) { #elif VERSION >= 3   if ( num >= 30 ) { #endif     num += 1;   } } C言語の文法と独立しているために、C言語の文法に合わないような書き方ができます。 ですから、行頭に記述して C言語のコードと混ぜないようにするというのは良い方法です。 それは理解できます。 しかし、このように書けることが便利と考えてよいのでしょうか。 マクロを定数と 同じ文法で使えるように括弧を付けて定義するなど、なるべく C言語の文法に近づける ことが推奨されます。 なぜなら、C言語の文法だけで読めればプリプロセッサーを 勉強しなくてもよいですし、プリプロセッサーが処理する内容に頭を切り替える必要 がなくなるからです。 たとえば、マクロの定義内容に括弧を必要としているのは、C言語の文法で使えるように するためです。 C言語の都合なのです。 #define SUM( x, y ) x + y total = ( SUM( a, b ) ) * 2; // total = SUM( a, b ) * 2; と書くと期待した動作をしない #define MULTI( x, y ) x * y total = MULTI( (a+1), (b+2) ); // total = MULTI( a+1, b+2 ); と書くと期待した動作をしない もし、マクロの定義に括弧がないものが混ざっていれば、マクロによって特殊な展開が されることを調べるきっかけになるように、マクロであることを識別しなければなら なくなり、すべて大文字にするなどのコーディングルールが必要になるでしょう。 C言語の文法のままで読める場合、プリプロセッサーであるかそうでないかが (コーディング ルールなどで)示されると混乱します。 内部の都合が外に出てしまって いるのです。 たとえば、英文字のフォントを描く処理が異なるために、英文字を赤色に して表示するということは、フォント描画の開発者にとっては有用であっても、一般の 読者には余計な情報であり、色に何か意味があるのではないかと混乱してしまうのですが、 それと同じことがマクロを使ったソースコードを読むときに発生してしまいます。 プリプロセッサーを行頭にすると、これもプリプロセッサーであるかそうでないかを 示してしまっている状況です。 インデントは、ブロックの範囲がすぐに読めるように するために行っており、読みやすさにおいて非常に重要なことなのですが、 それよりもプリプロセッサーであるかそうでないかを示すことの方が重要なはずは ありません。 #if INTERNAL_VERSION   #include "internal.h" #else   #ifndef NDEBUG     #include "public.h"   #endif #endif C言語の文法と独立しているためにできた書き方も、次のようにできます。 void func() {   num = Calc();   #define ADD 2   num += ADD;   #undef ADD } void func() {   #if VERSION >= 2     #define LIMIT 20   #elif VERSION >= 3     #define LIMIT 30   #endif   if ( num >= LIMIT ) {     num += 1;   }   #undef LIMIT } C++ 言語のテンプレートはプリプロセッサーのマクロと同様に事前に展開する処理が 行われていますが、プリプロセッサーとは言われません。 なぜでしょう。 違いは、 プリプロセッサー(cpp)をコンパイルする独立した処理系に入っているかどうか でしょう。 テンプレートには C++言語の要素が必要であるためプリプロセッサー に入れられないのが、プリプロセッサーから外れた理由です。 前処理(プリプロセス) だからではありません。 ちなみに、# は POSIX 系の設定ファイルやスクリプト ファイルではコメントとして 扱われることが多いですが、コメントにすれば C言語として処理されないために都合がよいと 考えたのでしょう。(ちなみに、# が行頭にしか書けないファイルもあります。) このようにコメントにコードを埋め込むような言語仕様にすることは混乱の元なのですが、 JavaScript ではかなり広まってしまいました。 JavaScript をサポートする前のブラウザーが多く使われていたときには 仕方なかったことなのでしょう。 しかし、コメントにコードを埋め込むことは 混乱の元なので、現在では JavaScript のコードを の中に入れません。 入れても使えるブラウザーもありますが、サイトが IE6 を対象外にするといった ような宣言をして撲滅していくことは可能です。 C言語から派生した言語では、プリプロセッサーを使えない言語の方が多いです。 プリプロセッサーは便利だと考えている人は、なぜ採用されないのか考えて みましょう。 それなのに、プリプロセッサーの都合を優先するのはどういうこと なのでしょう。 注目ニュース 一覧 ◇ Google、ChromeでローカルやGmail上のMS Office文書を編集できる拡張機能。 http://www.forest.impress.co.jp/docs/news/20140626_655376.html … Chrome が必要だがローカルで編集できるため高速。情報が洩れないかは不明。 ◇ オンラインバンキングの不正送金に注意。5月時点で年間最多被害額更新。 http://news.mynavi.jp/news/2014/07/02/050/ … 守る対象によってパスワードの強度(複雑さ)を変えよう。 ◇ アップルとGoogle、空から見下ろした東京を比べてみた。 http://www.itmedia.co.jp/pcuser/articles/1406/29/news008.html … すごいリアル。 ヘリ観光の気分。 ◇ Facebook、無断で行った情動感染実験について謝罪・釈明。 http://www.itmedia.co.jp/news/articles/1406/30/news044.html http://japan.cnet.com/news/business/35050302/ … わざわざニュースフィードを操作しなくても、分類して集めるだけでよかったはず。 ◇ 製造業は残業が少ない? 業種・職種別の残業時間ランキングをヴォーカーズが発表。 http://monoist.atmarkit.co.jp/mn/articles/1407/03/news047.html … 労働組合がない業界が多い。 ◇ 英国の映画館、Google Glass を客席で着用禁止へ。 http://japan.cnet.com/news/service/35050168/ … Google の理屈で言えば、電源を切ったカメラを構えても文句を言うなとなる。 ◇ グーグルの忘れられる権利対応で波紋。BBCの記事削除を受け。 http://japan.cnet.com/news/business/35050372/ … グーグル自身が懸念してきたことを全然対策していない。デメリットを示すためか。 ◇ OpenSSLの Heartbleed 脆弱性、サーバ30万台は修正気配なし? http://www.itmedia.co.jp/enterprise/articles/1406/24/news031.html … 更新すると動かなくなる可能性があることを理由にしているのか。 副作用を理解していない。 ◇ 中京銀行、IE6互換ブラウザとThinAppを利用しWindows XPからの移行を実現。 http://cloud.watch.impress.co.jp/docs/news/20140623_654708.html … マイクロソフトが規約を変えれば済むのに。 ◇ アルゼンチン政府、日本の新聞に悲痛な全面広告。債務返済を継続させてもらえない。 http://www.itmedia.co.jp/news/articles/1406/25/news128.html … 投資ファンドにも良い投資と悪い投資があるのに、投資ファンドは悪くないだけとは。 ソフトウェアデザイン館 Sage Plaisir 21 ホームページ >>> http://www.sage-p.com/ メルマガ >>> http://www.mag2.com/m/0000083983.html ブログ >>> http://blog.livedoor.jp/sage_p/ ツイッター >>> http://twitter.com/Ts_Neko ダウンロード >>> http://www.sage-p.com/freesoft.htm サポート掲示板 >>> http://www.sage-p.com/kg_ban09/z6037C8.cgi 東日本大震災 >>> http://www.sage-p.com/saigai.html メール >>> ts-neko◇sage-p.com ←◇を@に変えてください 緊急メールは件名に「うどんメール」を付けてください。 このメルマガの登録・解除 - http://www.mag2.com/m/0000083983.htm