continue文に振り回されてた

これが終わったら、これをやる……というのがずっと続いてきた仕事、

やっと終わりが見えてきた感がある。

1年ちょっと前からずっとこんな状況だった覚えがある。

まだプロジェクト全体としてはやるべきこともいろいろあるけど。


このプロジェクトの計画段階の甘さにはいろいろ思うところがある。

その中でメンテナンス用のソフトウェアを作る必要があった。

社内で作れる人を新規に割り当てるのはおおよそ困難な状況、

自分はマイコンをどうにかするのが優先である。

そんな中で外注に出して、一定の部分は業者のアイデアも借りながら作り上げた。

ただ、正直なところ、担当者の理解度が悪くて、こういうパターンではうまく動かないのだがと、

そんなことが開発期間中ずっと繰り返されていたのが実情である。


それでも普通に使う分にはあまり問題ないものはできた。

ちょっと気になる動きはあるけど、メンテナンス用のツールだし……

と、いろいろ使う中で、こういう使い方をするとエラーが出る仕様だよなと確認したら、

なぜかエラーが出ずに動いてしまうということが何度かあった。

とはいえ、とりあえず使う分には困らないので後回しだとやっていたが、

他の作業も一段落したのでバグを直していくかと作業をしていた。

とっくに検収は終わっているし、小修正だし自分でやりますかと。


ソースコード見ると、イマイチな作り方だなと思うところはけっこうあったのだが、

そんな中で考慮が足らんと思ったのが continue文のこんな使い方だった。

for(....){
   if(....){
     ....; continue; //A
   }
   if(....){
     ....; continue; //B
   }
   if(....){
     .... //C
   }else{
     .... //D
   }
   if(cnt >= CNT_MAX){
     .... //E
   } }

continue文というのはループの終わりまでジャンプする文である。

このfor文はデータを順次処理していくのだが、カウント数が一定に達すると出力処理(上記の処理E)を行う。

処理Aをしたら、以後のif文の判定もなく終わりまでジャンプ、

処理Bをしたら、以後のif文の判定もなく終わりまでジャンプという形である。

このように後ろの処理をスキップすることで効率的な処理にしたつもりだったのだが、

条件によっては処理Aの時点で処理Eを行うべき条件を満たすことがあり、

さらに他の条件が重なると、エラーも無く処理が終わってしまうが、生成されるデータは壊れていると。


なんでこれにcontinue文を使ったのかは謎で、

if(....){
   .... //A
}else if(....){
   .... //B
}else if(....){
   .... //C
}else{
   .... //D
}
if(cnt >= CNT_MAX){
   .... //E
}

とelse ifを連ねていけば無駄なく記述できるためである。

他にも考慮が漏れてるパターンがあり、正しく処理Eに分岐するように修正したら直った。


というわけであまりこれはcontinue文を使う意味はわからなかったのだが、

こういう処理を書いているとcontinue文を使った方がよいかと悩むことも。

for(....){
  ...
  if(!error){
    ....
  }else{
    ....
    if(!error){
      ....
    }else{
      ....
    }
  } }

でもこんな風にif-elseのネストを深くする方を選ぶかなぁ。

これはこれで読みにくいことも事実だが、さっきの処理Eみたいに後ろに必須の処理がある場合も多いので。


break文はないとうまく記述できないことも多いが、

continue文はなくてもあまり困らないんじゃないかなと思う。

コーディングルールで使用を禁止しているところも多いんじゃないか。

できるだけ手を加える範囲を小さくしながら問題を解決していくのに苦心したが、

全くダメなフローでもなかったので、ちょっと手を加えれば使えた。

これでとりあえず発見した問題は解決したはず。