̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ IT ニュース&コラム 2014/ 5/12 通巻661号 技術版 ソフトウェアデザイン館 Sage Plaisir 21  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ アドレスに &演算子を強制するな(2) - リーダブル・コード(22) 代入する文の右辺が関数名だったら、どのような処理をすると想像する でしょうか。 var = FuncA このように書かれている場合、その処理内容はプログラミング言語に よって異なります。 C言語や C言語の影響を受けた C++, C#, Java, JavaScript は、関数 FuncA の呼び出しをせず、var 変数に関数 FuncA のアドレスが入ります。 VBScript では関数 FuncA を呼び出して、 その返り値が var に入ります。 Ada というマイナーな言語もそうです。 関数名の後に括弧を付けた場合は、どの言語でも関数 FuncA を呼び 出して、その返り値が var に入ります。 つまり、VBScript は、() の 有無は関係ありません。 var = FuncA() ちなみに VBScript で関数のアドレスが入るようにするには、GetRef を使います。 Objective-C での関数呼び出しは C言語と同じですが、 オブジェクトへのメッセージ送信は、var = [ receiver metohd ] と書き、これも [ ] の有無で判断できます。 [ の位置が特殊ですが。 JavaScript では、addEventListener メソッドの第2引数に関数名を 指定することが多いでしょう。 document.getElementById("image1").addEventListener( "click", FuncA ); ほとんどの言語では、関数呼び出しでは () を書き、関数のアドレスを 参照するときは () を付けない書き方になっています。 この法則は、多く の言語で汎用的に使えます。 VBScript では右辺で呼び出すときに () を 書かない書き方を禁止にすれば法則が使えます。 Ada というマイナーな 言語はよく知りません。 &演算子(アドレス演算子)は、C/C++言語にしか存在しません。 しかも、 C言語では、関数名は、関数型、関数ポインター型、関数指示子 (function designator) のどれかに分かれます。 そして、それらの関係は非常に複雑 でありつつ、ほとんど意味がありません。 C言語の仕様書に書かれていることをそのまま列挙すると次のようになります。 ・関数名単体は、関数型です。 ・関数型は、関数ポインター型とは異なります。 ・関数指示子(function designator)は、関数型をもつ式です。 ・sizeof 及び単項&演算子オペランド以外の関数型の式は、  その関数へのポインタ型の式に変換される ・関数ポインター型に ( ) を付けると、関数呼び出しになります。 ・関数ポインター型に * を付けると、関数指示子(関数型)になる ・関数型に単項&演算子を付けると、関数の先頭アドレス(関数ポインター型)  になる ・関数の先頭アドレスに対して単項&演算子は付けられない ・関数ポインター型変数に単項&演算子を付けると、ポインターへのアドレス  になる 関数型に単項&演算子を付けると、関数の先頭アドレス(関数ポインター型) なるのですが、&演算子がなくても関数型の式は、その関数へのポインタ型の式に 変換されるため、以下は、どの行も同じ処理をします。 var = FuncA; var = &FuncA; (&&FuncA はエラー) 関数ポインター型に * を付けると関数指示子(関数型)になり、関数型の式は その関数へのポインタ型の式に変換されるため、* を付けても変わりませんし、 * を並べても同じです。 以下は、どの行も同じ処理をします。 function_pointer() (* function_pointer)() (****** function_pointer)() 関数名に & と * を演算しても無効になるような仕様になっている理由は、 関数名を、関数の先頭アドレスとみなすか関数本体とみなすかの争いに 決着がついておらず、互換性のために仕様を触らずに残っているのだろうと 私は推測しています。 ・StyleP. 関数名を関数の先頭アドレスとみなす書き方(関数名=FunctionAddress) void (* function_pointer )( void ) = FunctionAddress; function_pointer(); // = FunctionAddress(); // 関数ポインターに () を付けると呼び出し ・StyleB. 関数名を関数本体とみなす書き方(関数名=FunctionBody) void (* function_pointer )( void ) = &FunctionBody; (* function_pointer )(); // = FunctionBody(); // & したものは * で戻さないと 関数呼び出しを (* function_pointer )() のように * を付けて書く書き方は、 あまり見られません。 普通の関数呼び出しと書き方が違いすぎるために 読みにくいからです。 書くのも面倒です。 なので、* を付けない function_pointer() の書き方にすると、関数名は関数のアドレスと解釈した 方がよくなります。 なぜなら、読むたびに & したものは * で戻すという法則 (変数での法則であるが、C言語の仕様を厳密に読んだ人だけ関数には適用する 必要がないと気づく法則)に気がついてしまい、レビューのたびに C言語の 仕様を再確認するという無駄な工数が発生してしまうためです。 なので、 関数名に &演算子を付けない方がいいでしょう。 しかし、関数のアドレスを参照するときは &演算子を強制するルールが存在 します。 このルールを見て多くの人は、次のようなコードを書くでしょう。 ・StyleF. void (* function_pointer )( void ) = &FunctionBody; function_pointer(); しかし、このコードは、& したものでも * で戻さなければならないと誤って 判断してしまう中級者によって (* function_pointer)() を書かなければ ならないという誤った指摘が発生してしまいます。 Java, JavaScript, Obejctive-C など他の Web 系の言語を知っている人は、アドレスのアドレス って何?と迷うでしょう。 余計な工数です。 つまり、& 記号を必ず付けるコーディング・ルールがあると思われるソースを 読むときは中級者がからむと工数がかかり、& は効果がないことを知っている 上級者でなければ問題がないことを説明できないコードということになります。 それぐらいなら、() のない関数名はアドレスであるという法則だけを知って おくだけでよく、応用もききます。 & があるものがアドレスであるという 法則を広く適用することは、前回に説明した配列と同様に矛盾が発生する という副作用があるのです。 ソース: 組込みソフトウェア開発向け コーディング作法ガイド[C言語版]Ver.1.1 M1.5.1 関数のアドレス取得の演算や比較演算を省略しない。 注目ニュース 一覧 ◇ Internet Explorer の脆弱性対策について(CVE-2014-1776) - IPA 。 http://www.ipa.go.jp/security/ciadr/vul/20140428-ms.html … 結果としては風評被害のみだったが、いい訓練になった。 ◇ OAuthとOpenIDに深刻な脆弱性か。Facebookなど大手サイトに影響も。 http://japan.cnet.com/news/service/35047497/ … Facebook のアカウントでログインできるサイトが怪しいときに問題になりそう。 ◇ Google Safe Browsing APIは無意味? ほか。 http://internet.watch.impress.co.jp/docs/column/security/20140502_646836.html … Google Safe Browsing API という仮説を検証してみたら。 ◇ Google Glassで飛行機を整備、JALとNRIがウェアラブルデバイス活用の実証実験。 http://monoist.atmarkit.co.jp/mn/articles/1405/07/news027.html … 整備士なら Google Glass を身に着けていても怪しまれない場所がある。 ◇ サムスン Gear Fit レビュー。フィットネス向け曲面ディスプレイ搭載スマートバンド。 http://japan.cnet.com/news/commentary/35046958/ … 腕時計をする文化が廃れた今、厚さがカッコ悪い。 ◇ ソニーモバイル、リストバンド型の SmartBand SWR10 を5月23日に発売。 http://www.itmedia.co.jp/mobile/articles/1405/08/news053.html … 思い切って画面をなくして、スタイリッシュに。 ◇ モーションセンサー搭載でスワイプ&ジェスチャー操作が可能なキーボードをMicrosoftが開発。 http://gigazine.net/news/20140430-type-hover-swipe/ … 面白い。 ただ、マウスに求められる正確なポイントをするのが難しそう。 ◇ 現役世代の1TバイトSSDが3万円台に。 http://www.itmedia.co.jp/pcuser/articles/1405/03/news013.html … クルーシャル製。 現在は 5万円強。 ◇ コンピュータの認証をなぜ Log in と呼ぶのか、その知られざる由来とは? http://gigazine.net/news/20140430-origin-of-log-in/ … 勝手に複合語 login を作って使ってきたエンジニア。 一般的な欧米人はサインインがしっくりくる。 ◇ マイクロソフトがリリースした新たなWindowsストアアプリ開発ツール Project Siena を使ってみた。 http://www.buildinsider.net/mobile/projectsiena/01 … エクセル アプリケーションを作る人向けの Windows ストアアプリ開発ツール。 ソフトウェアデザイン館 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