e34.c

if 文の中がカラッポ!


if(val ==1) ;誤って『;』を記述した { ここには必ず来る }
解説 詳細は、 C-FAQ 10.4J 16.1J 20.14J C-FAQ 16.1E を参照して下さい。

事例紹介1	危険なマクロ:	
マクロ使用時、セミコロン記述し忘れると、
	次の行がelse節になる。
────定義側─────────────
#define MACRO(arg1,arg2) if(1) {¥
	松 ;	¥
	竹 ;	¥
	梅 ;	¥
} else				/*  セミコロン無し	*/
────参照側─────────────
	MACRO	/*  セミコロン忘れた	*/	
	ビックリelse節 ;


事例紹介2	
	『省略時のelseを必ず記述する事』と言う先輩の教えが形骸化したもの、	
        この様なelseを推奨する文献を私は知らない。

        if(松) {
                処理色いろ ;
        } else ;

        if(竹) {
                処理色いろ ;
        } else ;

        if(梅) {
                処理色いろ ;
        } else ;
先輩が言いたかったのは、
        if(松) {
                処理色いろ ;
        } else if(竹) {
                処理色いろ ;
        } else  if(梅) {       
                処理色いろ ;
        } else { /* このelseの事だと思う */
                異常処理
        }
蛇足であるが、elseをづらづら記述するより、switch文の方が処理速度が早い。
        switch(木)     {
        case    松:    処理色いろ ;   break ;
        case    竹:     処理色いろ ;   break ; 
        case    梅:     処理色いろ ;   break ; 
        default:       異常処理        break ; 
        }

事例紹介3      巨大マクロ
高速化するために、
巨大マクロを作成してもコンパイラの最適化の邪魔になるだけで
苦労の割りにむくわれない。
巨大マクロ関数化した方が良い。
もしくは分割する。
修正前:
#define         huge(ARG)       {       ¥
                switch(ARG) {           ¥
                case    松:            ¥
                        巨大処理  ;    ¥
                case    竹:             ¥
                        巨大処理  ;    ¥
                case    梅:             ¥
                        巨大処理  ;    ¥
                }
}
修正後:
#define huge_松()       {松処理 }
#define huge_竹()       {竹処理 }
#define huge_梅()       {梅処理 }

/************************************************************************/ /******* *********/ /******* *********/ /******* マクロは推奨しないが、 *********/ /******* どうしてもマクロを使用したい時はこのスタイル *********/ /******* *********/ /******* 1999.10.29 *********/ /******* 初版 NEC通信システム *********/ /******* *********/ /************************************************************************/ #include #include char buf1[0x7fff] ; char buf2[0x7fff] ; struct tag { int cnt ; struct tag2 { char foo ; char bar ; char baz ; char dmy ; } req[1] ; } ; /********************************************************/ /* 推奨しないマクロ */ /********************************************************/ #define badMAC() ¥ if(1) { ¥ tp->req[tp->cnt].foo = 'm' ; ¥ tp->req[tp->cnt].bar = 'a' ; ¥ tp->req[tp->cnt].baz = 'c' ; ¥ } else /* セミコロン無し */ /********************************************************/ /* どうしてもマクロを使用した時はこのスタイル */ /********************************************************/ #define goodMAC() ¥ do { ¥ register _i_ = tp->cnt ; ¥ tp->req[_i_].foo = 'm' ; ¥ tp->req[_i_].bar = 'a' ; ¥ tp->req[_i_].baz = 'c' ; ¥ } while(0) /********************************************************/ /* 呼び側関数群 */ /********************************************************/ static void bad(struct tag *tp) { badMAC() ; badMAC() ; badMAC() ; } static void good(struct tag *tp) { goodMAC() ; goodMAC() ; goodMAC() ; } int main() { int i ; struct tag *p1 = (void *)buf1 ; struct tag *p2 = (void *)buf2 ; for(i = 0 ; i < 128 ; i++) { p1->cnt = i ; good(p1) ; p2->cnt = i ; bad (p2) ; if(memcmp(buf1,buf2,sizeof(buf1))) { printf("%d¥n",i) ; fflush(stdout) ; abort() ; } } return(0) ; } /usr/abiccs/bin/cc -Kopt=2 vs.c -o vs pixie ./vs -o vs.P pixie registers: r31, r30, and r19. old code = 2896 bytes, new code = 10344 bytes (3.6x) vs.P prof -pixie vs vs.Addrs vs.Counts

対戦結果

---------------------------------------------------------------------------- * -p[rocedures] using basic-block counts; * * sorted in descending order by the number of cycles executed in each * * procedure; unexecuted procedures are excluded * ---------------------------------------------------------------------------- 11760 cycles cycles %cycles cum % cycles bytes procedure (file) /call /line 5888 50.07 50.07 46 ? bad (vs.c) 3072 26.12 76.19 24 ? good (vs.c) 2716 23.10 99.29 2716 ? main (?) 56 0.48 99.76 56 ? _start (?) 13 0.11 99.87 13 ? _fini (?) 13 0.11 99.98 13 ? _init (?) 2 0.02 100.00 2 ? __zeromem (?)