2016/07/08

[java]breakラベルはうらやましい

あまり、Javaに対して「ここがよい」とか「ここが悪い」とかは思わない。
まあ、unsignedがないのはめんどくさいとは思うのだが、そういう言語だしね、と思うことにしている。

ただ、breakについてはJavaがうらやましいと思った。
多重ループを抜けるときが、Cだとあまりきれいに行かないのだ。
私はこういうときのgoto文を許容するのだけど、プロジェクトとかによってはgoto一切禁止、ということもある。
多少は戦うのだけど、そういう文化のところなんだから仕方ない、とあきらめることの方が多い。

そういえば、switch以外でのbreak禁止、なんてところもあった。
ループを抜けるためにフラグを追加したりしたけど、逆にわかりづらいと思うのだけどねぇ。


そういえば、C++だとgotoでスコープを抜けたらデストラクタが動くんだろうか?
いや、動くのだと思うけど、けっこうめんどくさくないか。
どうやって「スコープを外れた」というのを監視してるんだろう。。。

だいたい関数に入ったら、レジスタをいくつかPUSHして、スタック変数を確保して、とやっていると思う。
ただ、抜けるときの動きがよくわからんな。

#include <stdio.h>

class ClassA {
public:
    ClassA()
    {
        printf("ClassA ctor\n");
    }

    ~ClassA()
    {
        printf("ClassA dtor\n");
    }
};

class ClassB {
public:
    ClassB()
    {
        printf("ClassB ctor\n");
    }

    ~ClassB()
    {
        printf("ClassB dtor\n");
    }
};


int main(int argc, char* argv[])
{
    printf("main - begin\n");

    for (int lp1 = 0; lp1 < 10; lp1++) {
        ClassA cla;
        for (int lp2 = 0; lp2 < 80; lp2++) {
            ClassB clb;

            if (lp2 == 71) {
                goto CATCH;
            }
        }
    }

CATCH:
    printf("main - end\n");
    return 0;
}

$ ./tst
main - begin
ClassA ctor
ClassB ctor
ClassB dtor
ClassB ctor
ClassB dtor
ClassA dtor
main - end

うん、"main - end"の前にClass Aのデストラクタが動いている。
Class Bよりも後なので、スコープが外れる内側から順番に呼ばれているのだろう。

arm-none-eabi-g++ -Sでアセンブラにしてみたのだが、なんかよくわからん。
main()の中でClassAのデストラクタだけ2回呼ぶ処理が入っている。
__cxa_end_cleanup()があって、これは何か最終処理っぽいものだったような気がする。

71と比較してイコールだったときのルートを追っていくと、確かにClassBのデストラクタ→ClassAのデストラクタという順で呼んでいた。
最後のClassAデストラクタも呼んでいるので、このときに2回呼ばれることになる。

ClassAのデストラクタを見たけれども、1回処理したら2回目以降はしない、みたいな処理は書いてないように見えるなぁ。。。
あまり読み方がわかってないせいかもしれん。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。