INASOFT 管理人のひとことフリーソフトダウンロードサイト「INASOFT」の管理人 矢吹拓也 が日々の「ひとこと」を語るページです。 2021年1月1日より、旧ブログ(blog.inasoft.org)からお引越ししました。 ・INASOFT Webサイト: https://www.inasoft.org/ ・管理人のふたこと(長文記事/寄稿文): https://www.inasoft.org/talk/ 2022年7月下旬より再び本業多忙化してきているため、更新頻度は落ちます。 [2022/7/24 19:32] Tweet ■C言語のORはどのように実装される?2014年11月17日(月) 0:00:00 [さくらのブログから転記] |
RSS配信中 | |
先日、Twitter上で「プログラマを探すには」みたいなジョークネタが流行っていました。 プログラマが考えている常識と、一般の人の考えている常識の違いを利用するというもので、例えば「=」という記号を「等しい」とみなすか「代入」とみなすか、とか、「AまたはB」という言葉を、「AとBのどちらか一方で、両方ともではない」とみなすか「AとBのどちらか一方、あるいは両方とも」とみなすか、の違いとかですね。 さて、そんな「または」なのですが、論理和としての「または」なのか、あるいは条件分岐としての「または」なのかで、ちょっと意味が変わってきたりもします。 C言語で言うと「|」と「||」の違いですね。 c = a | b; と書いた場合、aとbを構成するすべてのビットの論理和が計算されますし、仮にaとbが副作用の伴う式であったとした場合は、aもbもどちらも評価されます。 (例えば、 c = a() | b(); と書いた場合は、a() の関数呼出しは行われるし、b() の関数呼出しも行われる) 次に c = a || b; と書いた場合、おそらく c に入るのは、0か0以外(おそらく1)という保証しかされません。論理和の計算ではなくて、式を評価するための計算が行われます。また、ショートサーキット(短絡評価)が行われるため、aが真ならばbの評価は行われません(行われてはならない)。 (例えば、 c = a() || b(); と書いた場合は、a() の関数呼出しは行われるが、b() の関数呼出しが行われるとは限らない。a()の結果が真ならばb()の呼出しは行われてはならない) さて、C言語のコンパイル結果は、究極にまで最適化されるのが常ですから、これがアセンブリコードにどうコンパイルされるのか、見物です。 実際、Visual Studio 2010 で試してみました。 コンパイルしたプログラムは、こんな感じ。 #include "stdio.h" c = 1||2のようにしてしまうと、実際には c = 1という最適化がされてしまって、面白くありません。 また、a = 1; b = 2; c = a || b; と書いたとしても、コンパイラの高度な最適化によって c = 1 というコードが生成されたりしてしまいます。最近のコンパイラは大変頭が良い。 素直にOR演算のコンパイル結果を知りたい場合は、関数の引数を利用するとか、上で書いたようなscanfの結果を利用するなどしなければなりません。 さて、そのコンパイル結果のアセンブリコードは、こんな感じになっておりました。 TITLE ***** 赤字で示した部分が、該当箇所。 片っぽずつ cmp で評価し、条件ジャンプで飛んでますね。 (ちなみに cmp(比較命令)は、内部的には sub(減算)の結果をフラグレジスタにだけもたらし、減算結果の値そのものはレジスタへ格納しないという命令。cmp(sub)の引数に与えられた数値同士が等しければ、引き算の結果は0になるから、ZF(ゼロフラグ)=1になるということを利用する) で、その後のjne(ZF≠1なら指定のアドレスへジャンプ)。 そりゃそうか、ショートサーキットを実現するには、これが一番手っ取り早い。 (ショートサーキットは実現する義務があるからね) こういうのを研究するのも面白いんだよなぁ。 目次の表示: ブログではないので、コメント機能とトラックバック機能は提供していません。ご質問・ご意見等はメール、フィードバックまたはTwitter等からお願いします。いただいたご質問・ご意見などは、この「管理人のひとこと」の記事に追加、あるいは新規の記事にする形で一部または全文をそのまま、あるいは加工させていただいた上で、ご紹介させていただく場合があります。 当サイトでは掲載内容による不具合等に関する責任を持ちません。また、内容の正確性についての保証もありませんので、情報をご利用の際は、利用者の自己責任で確認をお願いします。 |
- 最近の更新 - |
|
3214203 (+0269)[+0672] Copyright© 2010-2024 INASOFT |