こんばんは、いつもお世話になります。ミミです。
他人が作成したプログラムを引き継ぐ事になり、
ソースを見ていたところ、下記に示すようなソースに出会いました。
(要点だけ抜き出します。)
--------------------------------
CHogeDlg::OnButton1()
{
Top:
ULONG lnHensu1;
TCHAR szHensu2[100];
(処理A)
if(ある条件の成立時)
{
goto Top;
}
}
--------------------------------
ある条件が成立した時、この関数(OnButton1())の「処理A」に制御を戻して
いるのですが、こともあろうに、goto Top; と、変数の定義文の所まで戻っています。
何回も goto Top; が成立するような場合、何度もローカル変数が定義される事になり、
メモリーリークが起きるのではないかと思い、簡単なゴミプロを作成し、タスクマネージ
ャ
でメモリ使用量の増加を見ていましたが、いつまでたっても、メモリ消費量が上昇して
いくような事はありませんでした。
既に運用に乗っているプログラムの為、問題なければ修正は行うつもりはありませんが、
皆様のご助言(このコーディングは良くないとか、やはりメモリを消費するなど)を
お願いしたく、書き込ませて頂きます。
# そもそも、ちゃんと考えて作っていれば、goto 自体、あまり使うことは無いとは思う
のですが・・。
環境は Windows2000、Visual C++ 6.0、MFC は使用しています。
以上、よろしくお願いいたします。
確認したわけじゃないけど大丈夫だろ。
コンパイラがへんなことしない限り。
提案ですが、アセンブリを吐いてデバッガで観察してみてはどうですか?
言語規格書 ISO/IEC 14882:1998 6.6 Jump Statements - 2 において、
自動変数の宣言より前に戻る飛越し文での移動は、その自動変数を解体する
(意訳 : より厳密な文言については原文ないし JIS X3014 を参照)
とあります。
VC++6 は言語規格書 ISO/IEC 14882:1998 より古い処理系ですが
この動作はサポートしています。
「メモリ消費量が増える」様な無駄なことは起きないので安心すべし。
メモリ消費量は増えないけど、デストラクト→再コンストラクトは起こっている。
まあ提示の例では POD なので実質何も起こらないけど。
でもこの場合Goto使わないほうが良い可能性が高いような気がします。
Goto禁止のコーディングルールは正しいとは思いませんが、無闇なGotoも正し
いとは思えません。
先頭に戻る意味が「繰り返し処理である」のなら単純にdo-whileで全体を囲っ
て条件を逆にして複数箇所で戻っている場合はcontinueにすればそのままルー
プに書き換えられるような気がします。
そのほうが意味に忠実なコードだと思いますし、今後そのコードを見る人が貴方
の様な疑問を抱かなくて済むと思います。
それと初期化処理と終了処理が一組になった物を使う場合、先頭に戻る前に
終了処理をしないと初期化のみ複数回行われる可能性があります。
上手くクラスにラッピングして有ればいいですがそうでない場合はメモリ以外にも
考慮したほうが良いと思われます。
ミミです。
超初心者さん、iuytさん、tetrapodさん、通りすがりさん、
ご返信ありがとうございました。
私からの Reply が遅れてしまいまして、申し訳ありません。
iuyt さん、有益なアドバイス、ありがとうございました。
ですが、当方の技量不足により、iuyt さんの提案するアセンブリでの
デバッグを実施することができません。大変申し訳ありません。
超初心者さん、tetrapodさんのアドバイスでは、
特に問題はないとの事でしたので、本件につきましては、
とりわけ修正の必要は無いものと判断し、解決とさせて頂きます。
但し、通りすがりさんもご指摘してくださっている通り、
決してスマートな書き方では無いため、時期見計らって、見直したいと
考えています。
(強制的に飛ぶ様なソースでは、バグも誘発しやすいですし・・。)
正直、言語規格書たるものの存在も今回初めて知りましたし、それに
自動変数の宣言より前に戻る飛越し文での移動について記載があるとは、
ビックリでした。
今回の書き込みでは、非常に有益な情報を得ることができました。
皆様、ありがとうございました。