gotoを使ってみる
大学時代にCを学んだとき、誰に言われたか「gotoは基本使うな」というのがやたらと頭にあって、それ以来バカの一つ覚えみたいにgotoを知らないCプログラミングをしてきた私です。
しかし、会社に入ってから使いどころさえ間違えなければgotoは有用に使えるということを教わりました。そのときに教えてもらったのは以下のサイト。
まだ実戦では使用したことはないのですが、ちゃんとした使い方を知らないままというのも癪なのでちょっとしたコードを書いてみました。(上記のサイトでほとんど言い尽くされている感はありますが、やっぱり自分でコードを書いてみないことには実感できないかな、と)
コード
#include <stdio.h> static int retA; static int retB; #define printfunc() printf(" %s\n", __FUNCTION__) static int initA() { printfunc(); return retA; } static int initB() { printfunc(); return retB; } static void uninitA() { printfunc(); return; } static void uninitB() { printfunc(); return; } static int mainroutine() { printfunc(); return 0; } static int testcase() { int ret = -1; if (initA() < 0) { goto endA; /* initA()が失敗したらすぐに戻る */ } if (initB() < 0) { goto endB; /* initB()が失敗したらuninitAして戻る */ } ret = mainroutine(); /* mainroutine()が終わったら、uninitA()とuninitB()してから戻る */ uninitB(); endB: uninitA(); endA: return ret; } int main() { printf("成功するケース\n"); retA = 0; retB = 0; testcase(); printf("initAで失敗するケース\n"); retA = -1; retB = 0; testcase(); printf("initBで失敗するケース\n"); retA = 0; retB = -1; testcase(); return 0; }
実行結果
成功するケース initA initB mainroutine uninitB uninitA initAで失敗するケース initA initBで失敗するケース initA initB uninitA
ちゃんと思ったとおりの経路で実行してくれています。
今までだったら"goto endB;"と書いてあるところで、"uninitA(); return -1"とか書いてるところだった。