C
C++
リファクタリング
ANSI
レガシーコード

引き継いだモジュールに存在した、理解が難しかったコード

組込み系は歴史が古く、自分が生まれる前のコードが現役で動いてることが多い。
そういえばこんなのもあったなあというメモ。
見つけたら適宜追加。

古い規格

sample.c
 func(a, b)                      
 int a, b;                       
 {                                       
       .                                 
       .                         
 }

K&R規格であるためANSI規格とは関数定義の方法が異なる。
今後誰がこのモジュールを触るか分からないため(もしかしたら新人かもしれない)、現行の規格に則った定義に変更して他モジュールと統一した。
(追記)
ANSI規格で関数定義していれば完全に正しいようなプログラムでも K&R スタイルで書くと正しくなくなる (そしてそれがコンパイルエラーにならない) 場合が有る。(また、C++ ではこのスタイルは廃止)

たらい回し

sample.c
AAA[(UH)BBB[(UH)CCC[(UH)DDD[(UH)EEE]]]]

別の場所にテーブルが作られており、それを参照するためのコード。
EEEを貰って、それからDDDを参照し、そのDDDからCCCを参照...といったように役所ばりにたらい回しにされるコード。
特に説明コメントがあるわけでもなく、一見しただけでは意味が分からなかった。
テーブル周りは今後触ることは無さそうなので、単純に上記コードをバラけさせて説明コメントを追加した。

マンモス構造体

sample.c
typedef struct {
        int a;
        int b;
        int c;
        //以下、なんかめちゃくちゃでかい構造体
        hoge hoge_struct;
        foo foo_struct;
        bar bar_struct;
    }sample_struct;

数千バイトもあるような構造体があると、スタックの管理がしっかり出来ていないとすぐスタックオーバーフローを引き起こしてしまう。
過去見たコードだと、

  • ローカル変数として上記のようなマンモス構造体を宣言
  • 適当なget関数に宣言したマンモス構造体のポインタを渡してデータを得る
  • 得たデータをほんのちょっとだけ使う

等をしている箇所があった。
マンモス構造体の一部しか使わないなら、必要なデータだけを得る関数を作るなど別の方法でデータを得る方が良い。
そもそもマンモス構造体が出来ないようにすることが大事。
しかし組み込みの現場では古いコードを秘伝のタレの如く継ぎ足し継ぎ足し追加していくので、最初書かれた時はマンモス構造体ではなかったが、年月によりマンモスになってしまったパターンが多い。
そういう時はリファクタするか、見なかったことにしてそっと閉じよう。