LoginSignup
3
2

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-04-08

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

古い規格

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関数に宣言したマンモス構造体のポインタを渡してデータを得る
  • 得たデータをほんのちょっとだけ使う

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

3
2
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2