例外処理 例外型が不明な場合について – プログラミング – Home

例外処理 例外型が不明な場合について
 
通知
すべてクリア

[解決済] 例外処理 例外型が不明な場合について


wood
 wood
(@wood)
ゲスト
結合: 23年前
投稿: 895
Topic starter  

OS:WinXP VC6(SP6) コンソールアプリ

以下のサンプルがありました
------------------------------------------------------------------
#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{

 try
 {
 int request;
 cout << 整数を入力してください:;
 cin >> request;

 if(request == 1)
   throw THIS IS ERROR;
 else
   if(request == 1)
      throw 10;
   else
      throw 1.23;  ←ここ.1

 }

 catch(char* e)
 {
  cout << char*型エラー発生: << e << endl;
 }
 catch(int e)
 {
 cout << int型エラー発生: << e << endl;
 }
 catch(...)   ←ここ.2
 {
 cout << その他 << endl;
 }
return 0;
}
-------------------------------------------------------------
このサンプルの「ここ.1」の例外(Double型)は「ここ.2」でしか
判断できませんが
仮に「ここ.1」の部分が関数だった場合、関数内部で型が不明なthrowを
発生させていたとすると、どのようにしてますでしょうか?

1、サンプルのように「その他」で終わらせ、あきらめる以外ない
2、他に値を取得する方法がある
3、そんな記述は絶対しない(ありえない)

どれでしょうか
3の人は回答不要(他人の作った関数やDLLを使用しない人でしょうから)

もし 2があるのなら是非教えてください


引用未解決
トピックタグ
Ban
 Ban
(@ban)
Prominent Member
結合: 5年前
投稿: 776
 

ソースがあるなら検索なりできるとして、ここではソースもないとして。
「投入されうる例外」はその関数のインターフェイスの一部ですので、
製作者に仕様を確認するしかないのではないかと思います。
そのコンタクトも取れず保守も保証もない代物であれば、1 で我慢しかないような気がします。

2は多大な労力をかけたリバースエンジニアリング(ライセンスに問題がなければ)くらいしか方法はないと
思います。(組み込み型の double なら多少楽かも?)

# ありえないとは言いませんが、自分で書くなら 3 を守りたいです。


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

throw THIS IS ERROR; を catch(char* e) で取得できないことはおいといて

まったく不明な例外を投げるのであれば、可能なのは「受け取るだけ」であり、詳細を判別する
ことは不可能です。
つまり解は1

C++ 標準ライブラリは std::exception 派生型の例外を投げることで「まったく不明」な例外
を排除しています。
ということで、ライブラリを作る側と使う側で合意が取れるのなら、
解3「特定基底クラス派生の例外オブジェクトを投げる」
ようにすることが望ましく、まったく不明な例外など使わないに1票。

合意もソースも仕様書も無いなら解1しか手はないです。
# リバースエンジニアリングしてまで解2の策を取りたくはないなぁ。


返信引用
REE
 REE
(@REE)
ゲスト
結合: 23年前
投稿: 240
 

仕様が不明な例外を受けた場合は、その意味するところも不明でしょう。
よって、その型や値がわかっても、使い道はないでしょうから、1で充分と思います。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

思うに、catch(...)は正にいわれているような事態に対応するための手段だと思います。
補足しないとアプリが意図しないダイアログが出てしまいますから、
それを出させないで全て使う側の管理の下に表示等を行う為の最終手段ではないかと。
皆さん言われているように、何がくるのかわからない例外では使いようがないというのが
正道でしょう。基本的に仕様として規定されていない物であれば、対応する処置は出来ない
ので、取り合えず受けたとしても「想定外の例外が発生しました」とでも出すしかなさそ
うですね。


返信引用
wood
 wood
(@wood)
ゲスト
結合: 23年前
投稿: 895
Topic starter  

皆さんの大変貴重なご意見ありがとうございます

「tetrapod さん」に至っては、サンプル提示ミスのご指摘まで頂きありがとうございます

>catch(...)
は皆さんの言うとおり、1の「あきらめる」ほか、なさそうですね
C++の基礎再学習を行っていましたら、突っ込んだ解説のようなものが見当たらず
皆さんの意見を伺ってみた次第です、ありがとうございました


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

ISO/IEC 14882 には throw(string_literal) を catch(char*) で受け取れない
と明記されています(「受け取れてはならない」という処理系作者への要請の意)
15.1 Throwing Exception 3

が VC++6 や bcc-5.5.1 では受け取れてしまいます。その意味でサンプルは正しいです。
gcc-3.3.4 では受け取れなくなっています。
# 規格書より古い処理系なのでしかたがないのですが > VC++6

文字列リテラルは const char* でなら受け取れるので catch(const char*) ならOK


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

「catch( ... ) はどうしようもない」と言うよりも、「どうしようもないから catch
( ... )」なのではないでしょうか。
何が言いたいかというと、catch( ... ) には、例外オブジェクトとして受け取る変数名
を書けませんよね。
こういう仕様が策定された時点で、解2は無いものとされていたのではないでしょうか。

ちなみに、VC++ 限定(バージョン依存かも。7.1 では大丈夫)の、可搬性のない方法な
ら、ひょっとしたら可能かもしれません。
0xe06d7363 でぐぐると、何か見つかるかも…


返信引用
wood
 wood
(@wood)
ゲスト
結合: 23年前
投稿: 895
Topic starter  

「tetrapod さん」「シャノン さん」 ありがとうございます
コンパイラによっては、制限事項が違ったりしますので必ずしもVCが正しいわけでは
無いことを肝に銘じておきます

「0xe06d7363」例外構造体番号と言うものらしいですね
MSDNには「WINDOWS OS 固有のもの」という表現がありました


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました