* OSECPU-ASKAの注意点
-(by [[K]], 2013.04.25)

** はじめに
-ASKAはC言語の文法をかなり真似したアセンブラですが、真似し切れていない部分もあります。
-どこが違いかを忘れないようにするためにメモを作りました。

** for文
-for文は違いが満載。見た目が似ているだけに混乱は小さくない。
-(1) 繰り返し範囲は必ず { } でくくらなければいけない。
--一文しかなくても、{ } をつけなければいけない。
--なぜこんな仕様なのかって?それはコンパイラが楽をするためだ。
-(2) for文の条件式が最初から不成立だったとしても、ループは一度は回ってしまう。
 for (;0;) {
     あれこれ
 }
 // こう書いても「あれこれ」は一度だけ実行される!
--C言語風に最初から不成立だった場合は一度も実行しない、というのがやりたいときはこうする。
 if (条件式) {                 // ifの条件式はforと同じ内容にする
     for (...; 条件式; ...) {
         あれこれ
     }
 }
--なぜこんな仕様なのかって?それは確実に一度は回るというループを書く頻度が相当に高くて、それなのにループをスキップさせるためのバイトコードを毎回出力させるのはムダだなあと感じたから。上記のように書けば一応回避できるし。
-(3) continue;文の挙動がC言語と違う。
--普通はcontinueを実行したら、for文中の更新式が実行されて、その後に条件式を評価して成立すれば次のループを開始する。しかしOSECPU-ASKAのcontinueは、更新式を実行しないし、条件式の評価すらしないで、いきなり次のループに突入する。
--このような仕様により、たとえば以下の記述は無限ループを構成してしまう!(C言語ではそうはならない)
 for (i = 0; i < 2; i++) {
     continue;
 }
--なぜこんな仕様なのかって?それはコンパイラが楽をするためだ。
--C言語相当にしたければ、continueの直前に、更新式や条件式の評価を入れなければいけない。
 for (i = 0; i < 2; i++) {
     i++; if (i < 2) continue;  // この一行がC言語でのcontinue相当になっている
 }
** if文
-(1) if成立節もelse節も必ず { } でくくらなければいけない。
--ただし例外がある。
 if (条件式) continue;
 if (条件式) break;
 if (条件式) goto ...;
--この3形式だけは { } でくくる必要はないし、くくらないほうが抜群によいコードを出力する。
--なおこれらの3形式は途中で改行してはいけない。つまり以下のように書いてはいけないということだ。
 if (条件式)
     continue;
--これがやりたいならコードがへぼくなることを承知の上で、以下のようにする。
 if (条件式) {
     continue;
 }
--以下のような書き方でもかまわない。
 if (条件式)
     { continue; }
--なぜこんな仕様なのかって?それはコンパイラが楽をするためだ。
-(2) else if は使えない。
--else節の中にifを入れることでほぼ同じことはできる。しかしネストは深くなってしまう。
--forやbreakを使って以下のように書くのがもっとも好ましいと思われる。
 for (;0;) {
     if (R02 == 0) {
         あれこれ
         break;
     }
     if (R02 == 1) { /* else-ifの代わり */
         いろいろ
         break;
     }
     if (R02 == 2) { /* else-ifの代わり */
         ほげほげ
         break;
     }
     if (R02 == 3) { /* else-ifの代わり */
         ふがふが
     }
 }
-(3) if成立節の最後がbreak;などのジャンプ命令だとしても、else節が後続する場合はelse節をスキップするためのジャンプ命令を出力してしまう。だからelse節を作らずにそのまま書いてしまうほうがよいコードになる。
--何を言っているのかよくわからないと思うので補足。
 // 書き方1
 if (条件式) {
     あれこれ
     break;
 } else {
     いろいろ
 }
 
 // 書き方2
 if (条件式) {
     あれこれ
     break;
 }
 いろいろ
--2つの書き方は同じ動作結果になるが、書き方2のほうがよいと言っている。
--なぜこんな仕様なのかって?それはコンパイラが楽をするためだ。
-(4) else を書くときは、直前の } と同じ行になくてはいけない。
 // OKな例
 } else {
 
 } else
 {
 
 // だめな例
 }
 else {
 
 }
 else
 {
--なぜこんな仕様なのかって?それはコンパイラが楽をするためだ。・・・同じ行でelseキーワードが見当たらないと(つまり探している間に改行を迎えてしまうと)、if分の終わりなんだなと誤認してしまう。
-(5) &&や||は(当面)使わない。
--その代わり&や|で代用する。これらは左辺値で真偽が確定するしないにかかわりなく右辺値を評価してしまうので注意がいる。たとえば「ポインタが正常な範囲に収まっているかどうかを確認したうえでアクセス」というパターンはよくやるけど、それが&ではできない。if文を分けることで対処するしかない。
 if (p < p1 && *p == 'a') { ... としたいとき
 
 if (p < p1 & *p == 'a') { ...  これはダメな書き方
 
 if (p < p1) {
     if (*p == 'a') { ...       これは良い書き方 
 
 }
--なぜこんな仕様なのかって?それはコンパイラが楽をするためだ。

** こめんと欄
-このページにこめんと欄はありません。このページの内容にコメントしたいときは[[impressions]]にお願いします。

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS