̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ IT ニュース&コラム 2014/ 9/29 通巻671号 技術版 ソフトウェアデザイン館 Sage Plaisir 21  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ #define のシンボルを大文字だけにするな - リーダブル・コード(27) C言語の #define マクロは、#define BUFFER_SIZE 256 のように、大文字だけのシンボル で定義することが多いです。 C言語の #define を学習する教材がよくそうなって いますが、そうしなければならい理由は単にプリプロセッサーによって置き換え られることを明確にすることで学習がしやすくなるぐらいでしょう。 この傾向によって、#define シンボルは大文字(のスネークケース)にしなければ ならないというコーディング ルールができたりします。 メリットは、やはり、 #define シンボルであるかどうかが、見てすぐに分かることぐらいでしょう。 このコーディング ルールは、対応することが簡単です。 なぜなら、#define されたシンボルかどうかだけだからです。 初心者でも簡単に対応することが できます。 しかも、大文字だけに変換するツールを作ることも簡単にできます。 ツールがあれば、確実にコーディング ルールを守ることができます。 簡単なことでルールを守っていることで、堅牢なプログラムである印象を提供する ことができます。 ルールを守っている忠実な開発者である印象も提供できます。 しかし、#define シンボルを大文字にするというコーディング ルールは、 様々なケースを考慮していない「乱暴な」ルールであり、すぐに「副作用」が表れる 対応が難しいルールなのです。 まず、ISO が定義している C言語の標準仕様に書かれている #define マクロは 大文字以外のものがたくさんあります。 たとえば、C99 には下記のようなサンプル があります。 一度は目にしたことがあると思います。 #define max(a, b) ((a) > (b) ? (a) : (b)) C99 を見ると、( ) が付いていない定数のようなマクロは大文字のスネークケース、 ( ) が付く関数のようなマクロは小文字のスネークケースになっている傾向は ありますが、完全に統一されているわけではありません。 6.10.3.5 Scope of macro definitions の EXAMPLE 4 を引用します。 #define str(s) # s #define xstr(s) str(s) #define debug(s, t) printf("x" # s "= %d, x" # t "= %s", \ x ## s, x ## t) #define INCFILE(n) vers ## n #define glue(a, b) a ## b #define xglue(a, b) glue(a, b) #define HIGHLOW "hello" #define LOW LOW ", world" INCFILE は ( ) がありますが、小文字ではありません。 ( ) があるかないか という「乱暴な」ルールを守りたくない理由があったのでしょう。 おそらく、 データは大文字、関数は小文字という「意味」で分けていることと思われます。 (データでも関数でもないマクロもあります。) 小文字にしている理由は、関数と同じスタイルにするためと思われます。 ISO の C言語の標準ライブラリの関数は、小文字のスネークケースになっている からそうなのですが、関数がパスカルケースにしなければならないというルール があったら、それに合わせた方がよいでしょう。 なぜなら、関数がマクロで定義するかどうかは、定義内容によるからです。 実装がインターフェースで隠し切れなくなるのです。 定義内容が単純なら、関数呼び出しのオーバーヘッドが大きくなってしまい、 マクロにした方が処理が速いからです。 そのため、標準ライブラリの ctype.h にある文字判定関数がマクロで定義されたコンパイラーもあります。 性能は ISO の品質モデル(FURPS+) の1つの要素(P)です。 もし、#define マクロを大文字にしなければならないルールが あったら、シンボルを大文字に変えなければならなくなってしまいます。 バージョンアップしたときにマクロに変わったから大文字に変えてしまうと、 互換性が無くなってしまいます。 こういった副作用に目をつむってはいけません。 そもそも、#define マクロであるかどうかは、内部的な情報なので、プログラム を読む上であまり重要な情報ではありません。 外部への情報、たとえば、 型を知りたいことの方が多いためそちらの方が重要でしょう。 コーディングルールは、外部への情報を検索する手間を省くことができる メリットがありますが、あまり多くのルールを持たせることができないので、 もっと重要なことにルールを作った方が良いでしょう。 #define が大文字でなければ違和感を感じる原因は、それがマクロであるかどうか ではなく、グローバル・スコープの定数であるかどうかです。 ただし、グローバル・ スコープ定数は、C 言語以外の多くのプログラミング言語でのスタイルは、 大文字のスネークケースではありません。 C言語プログラマー固有の違和感です。 政治的な理由で #define を大文字にしなければならないときは、 インライン関数を検討するのが1つの手です。 #if で切り替えられるようにしておけば、地域によって差がある政治的な 理由からくる実装依存をインターフェースの中に閉じ込めることができます。 #if も許されないなら、提供しないファイルに移動しておきます。 ただし、初期化子や、配列を宣言するときの配列要素数には、インラインでも 関数を指定することができません。 SampleClass g_SampleArray = SampleClass_getInitialValues( "Name" ); uint8_t g_Buffer[ GetBufferSizeFromItemCount( 10 ) ]; ソース ISO/IEC 9899:1999 - 6.10.3.5 Scope of macro definitions MISRA 19.7 : A function should be used in preference to a function-like macro SEC M5.1.3 関数形式のマクロよりも、関数を使用する 注目ニュース 一覧 ◇ Yosemiteまで待つ? iOS 8 アップデート、Appleが iCloud Drive について説明。 http://www.itmedia.co.jp/enterprise/articles/1409/18/news048.html … iCloud に入っていたファイルが見られなくなる重大な欠陥仕様。 ◇ アプリに新たな可能性が与えられた iOS 8。 http://k-tai.impress.co.jp/docs/review/20140918_667330.html … iOS8 の新機能一覧。 ◇ 特集。.NET開発者がよく使うサイト、本当に使えるサイト 2014年度版。 http://www.atmarkit.co.jp/ait/articles/1409/26/news109.html … .NET 以外でも使える。 ◇ アジャイル開発をトータルで支援、コラブネット TeamForge ALM 日本発売。 http://news.mynavi.jp/articles/2014/09/12/TeamTorge/ … チケットベースのアプリケーション・ライフサイクル管理ツールのようだ。 ◇ NEC、ハイブリッド開発プロセスを取り入れたシステム構築基盤の最新版。 http://news.mynavi.jp/news/2014/09/25/314/ … ウォーターフォールは、概要の仕様が決まったところで始めることが示されている。 ◇ Amazon が Microsoft化している5つの兆候。 http://www.itmedia.co.jp/enterprise/articles/1409/17/news016.html … Amazon がクラウドを独占している。 ◇ 出版不況再び。本・雑誌が売れないのは活字離れのせい? http://japan.cnet.com/sp/t_hayashi/35053789/ … ツッコミに科学的に応える良記事。 ◇ MS、Universal Mobile Keyboard を発表。AndroidとiOSもサポート。 http://japan.cnet.com/news/service/35053880/ … キーボードの配置の違いに対応しているのか。 ◇ Google、検索結果に製品スペックなどを表示する Structured Snippets を追加。 http://www.itmedia.co.jp/news/articles/1409/24/news067.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