例外処理exception, runtime_errorの使い方

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
例外処理の使い方、問題点を検討。

先ず1問目。
std::runtime_errorでエラー文字列を上に渡すことが出来ます。
しかし、多国語対応だとクラスの中に膨大な文字を持つようになります。
かといって、エラー文字列取得クラスなんて用意する、汎用的なクラスになりません。
やっぱ、runtime_errorは捨てて、素直にexceptionを派生するべき?
get_2_exception
先生、わかりません
4デフォルトの名無しさん:03/04/30 17:31
織田信長について語ってるの?
5デフォルトの名無しさん:03/04/30 17:39
そうそう、織田信長って良く構造化例外使ってたよね。
既存スレへどうぞ。

C++相談室 part18
http://pc2.2ch.net/test/read.cgi/tech/1050177746/
7デフォルトの名無しさん:03/05/01 00:07
文法じゃなくてアプリ構造についても考えたいYO!
特にエラー例外ってのにこだわらなければ使い道はいろいろあるかと。
たとえば、シーンチェンジに使ってたりします。
>>8
そういう使い方はやめろ。
>>9
なんで?結構便利だなって思ってたんだけど。
私はプログラムの経験が少ないんで問題に気づいてないのかもしれないですね。
できればシーン変更の標準的な方法を教えてほしい。
11デフォルトの名無しさん:03/05/01 08:39
>シーンチェンジ
なんだけ?RPG?
多重whileから一気に抜ける時に使います
gotoよりはいいでしょ。
13デフォルトの名無しさん:03/05/01 13:00
例外は遅くは無いとは聞いたことあるけど。
14動画直リン:03/05/01 13:13
多重whileというかメソッドからメソッドを呼んでとか多重入れ子になってる状態で
一気に親メソッドに戻りたいときはいいね。
>>12
おいおい
別会社のとあるコードみたときに、
本チャンコードが5行程度で
例外処理が30行以上のコード見たことがある。

「なんでや?」と聞くと
「あ、それ0で助産したときの処理です」とこきやがった。
確かにそのとおりだったが

・・・
18デフォルトの名無しさん:03/05/01 16:10
>>17
構造化例外にすると1行になるコードかい?
>17
例外処理のコードが少なすぎるって言いたいのかな?
20デフォルトの名無しさん:03/05/06 14:57
エラーメッセージの扱いどうしよう。

多言語対応したくて、組み込みからWindowsをカバーしたい場合。
gettextを使う
22デフォルトの名無しさん:03/05/08 05:05
スロウラブルで幸せを掴もう。
>>17
例外処理で30行?いいんでないの?
サーブレットの話しだけど例外発生したらエラー画面に飛ばすとかの処理
書いたらそれくらいならない?
画面に飛ばす処理を共通化するならn行で済むけど。
漏れはもっぱら RuntimeException の例外しか作らん
25デフォルトの名無しさん:03/05/08 08:36
今までBCBだったので、
throw Exception("")
したら、メッセージボックス出力されてました。
が、MFCのプログラムだと異常終了します。
MFCな人達はどうしてますか?
2625:03/05/08 09:18
ちなみに、MFCではthrow runtime_errorしてますが、
やっぱ、トラップを自分で書くしか無いかな。
BCBのプロジェクトファイルみたいなのはどこにあるんだろう。
27デフォルトの名無しさん:03/05/08 12:21
自作例外クラスはどう設計すればいいでしょう?

Exceptionクラスを継承してコンストラクタでsuper(String message)を呼び出しているだけで
終わってしまっていますが・・・
29デフォルトの名無しさん:03/05/09 00:00
std:::bad_alloc例外投げる時にさらにメモリ不足になったりしないかと夜も眠れません
>>25-26
CWinApp派生クラスのInitInstance, ExitInstanceと、
メインウィンドウのWindowProcでtry-catchしてSEH以外は全部捕まえてる。
特別なエラー処理をしたいハンドラはそのハンドラで独自にtry-catch。

>29
MFCのAfxThrowMemoryExceptionは
グローバル変数へのポインタを飛ばしてるだけだから
メモリを確保しない…んじゃなかったかな。

std::exception派生クラスでそういう仕組みは作れる?
> そういう仕組み
ってなあに?
32デフォルトの名無しさん:03/05/09 09:59
bad_allocとruntime_errorと、多重継承出来る?
「Javaの鉄則」本に、例外が現れたらそれらを上書きで隠さずにVectorクラスに溜め込む
技があったな。

Vectorに溜め込む専用の例外クラスまで用意していたが、
汎用性がどれだけ高くなるか疑問。
34デフォルトの名無しさん:03/05/09 15:26
>例外が現れたらそれらを上書きで隠さずにVectorクラスに溜め込む

役に立つの?
役に立つなら、C++版を作成しようかな、と。
35デフォルトの名無しさん:03/05/09 18:54
>>30
WindowProcでキャッチするのは確かに気持ちいいんだが、
例外をOSのDLLのスタックを通過させないように注意しろよ。動作が不定になるぞ。
サブクラス化した場合とかは特に、そっちのWindowProcでもちゃんと全catchするように。
3630:03/05/09 19:11
>>35
何か大変だね。やめとこう。
BCBなら普通に出来ることなのにね。
TApplication::OnExceptionていうイベントハンドラさえあるのに。
37bloom:03/05/09 19:13
38デフォルトの名無しさん:03/05/09 19:36
>>36
別に大変ではないからやりなさい。
3930:03/05/10 01:33
>>31
えーと、MFCの場合は
CSomeException g_GlobalException ; //CException派生、グローバル変数

throw &g_GlobalException ;
とポインタを投げるので例外処理時にメモリを新たに確保しない。
(スタックは使うのかな。分かんない)

STLだと
MyException g_E ; //std::exception派生、グローバル変数

throw g_E ;
と投げて受け側が
catch(std::exception& e)
と受けてもどこかで例外オブジェクトがコピーされちゃうんじゃない、か、
と思っちゃったんだけど…

コピーされないか。されませんね。すみませんでした…
4030:03/05/10 01:37
>>35
げ!?
OSのDLLのスタックを通過って、
DispatchMessage API の外側でtry-catchしちゃまずいとかそういうこと?
全然意識してなかったよ…。

#ところでこのスレって環境依存の話ばっかりしちゃまずい?
4130:03/05/10 01:41
>>36
って、キミは誰だ?オレか?

MFCにもCWinApp::ProcessWndProcException
というのがあるけどCException派生の例外しか処理してくれないのでね。
ぼく知ってるよ。throwで投げたものはぜったいコピーされるんだ。
dll内の関数が投げた例外って、dll内でcatchしないとアプリ落ちちゃいません?
44デフォルトの名無しさん:03/05/10 11:22
OSがDLLを提供するのは良いが、OSのDLLは関数ベースで例外出さなくて綺麗だよね。
VC++なんかの、DLLの例外をアプリがcatchすること自体キショイような気がする。
45デフォルトの名無しさん:03/05/10 17:08
>>28
うわっ、例外のコピーコンストラクタが例外を投げたら、terminate()
呼ばれるんだ。コンストラクタが例外投げたときと同じように、
新しい例外の方が有効になるんだとばっかり思ってた。
でも、よく考えると、例外オブジェクトの領域は普通は一箇所だから、
新しく例外を投げようとするとオブジェクトを上書きしてしまうのか。
46動画直リン:03/05/10 17:13
47デフォルトの名無しさん:03/05/12 17:07
VC++/MFCで、
std::runtime_errorを派生したいんですが、
なんかコンパイルエラーの嵐です。サンプルきぼんぬ。
48動画直リン:03/05/12 17:13
↑ぬるぽ刑
50デフォルトの名無しさん:03/05/12 22:50
以前読んだ本に
「コンストラクタで例外を投げるのはオススメできない」
って書いてあったんですけどコレはなんででしょう?
特に理由も書いてなかったし

今までバリバリ例外投げてたんですけど、これってマズイ?
マズクナーイ
>50
MSDNの"Deep C++"にあれこれ書いてある。
ttp://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/jpdndeepc/htm/deep01202000.asp

どうせアプリケーションを終了させなきゃならないような例外だったら投げても
いいかと思うけど。
>>52
第14部だけ張るとは、恐ろしい罠だな。
気をつけろよ。>>50
54デフォルトの名無しさん:03/05/14 02:06
つうか俺はほとんどコンストラクタ位でしか例外を投げてない
5552:03/05/15 00:10
>53
おお、言われてみれば。13部〜16部くらいがこのあたりの話。
でも全編読むべきなのだろうな。
…なんか難しくてよく分からんのだが。
なんか和訳がわかりにくいな
>>55
問題は、14部から後に筆者の意見が逆転してることだな。
58デフォルトの名無しさん:03/05/15 21:40
例外というのかわかんないんだけど、
Windowsアプリでint系の割りこみハンドラって作れるの?
 作れる
60デフォルトの名無しさん:03/05/16 00:37
例えば、
奇数アドレスを参照しようとしたら例外(int)飛ばす事にしたいんだけど、
できるんでしょうか。
61デフォルトの名無しさん:03/05/16 01:04
そもそも奇数参照で例外出す機能がx86にあったか?
ペナルティで実行クロック余計にかかるだけでは・・・最近の知らんが。
モトロラとかあっちならあったな。
無理やりunsigned longあたりにキャストして0x01とAND
MSVCP60.DLLから飛んでくるstd::ios::failureがstd::exceptionで捕まえられないんですが、
心当たりの在る方はいらっしゃいませんか。
RTTI有効にしてるのがイカンのだろうか・・・
64デフォルトの名無しさん:03/05/16 10:03
例外処理って使いどころがわからん・・・
例外処理しなければアプリが不正に動作してデータ壊したり、異常終了するだけですが...
>>64の言う例外処理はC++のtry&catchのようなものを指すのでは。

if使って書くよりよほど見やすいと思うけど・・・
たとえば、ファイルの入力をストリームと見た場合、
終端(EOF)は例外。
>>59
windowsの32ビットモードのアプリで
intのハンドラを書きたい場合どうすればいいんでしょうか?
というか、OSが提供してる割りこみの種類がわからないんですが・・。
MSDNとかに載ってますか?
69デフォルトの名無しさん:03/05/17 01:37
例外をキャッチしないとterminate()が呼ばれるわけだけど
set_terminate()で設定した関数の中で例外をスローするとどうなるんだろう?
しないほうがいいのは前提として
鼻から悪魔
71デフォルトの名無しさん:03/05/23 08:56
mainがC言語だと、throwするのも不安だね。
72山崎渉:03/05/28 12:50
     ∧_∧
ピュ.ー (  ^^ ) <これからも僕を応援して下さいね(^^)。
  =〔~∪ ̄ ̄〕
  = ◎――◎                      山崎渉
73デフォルトの名無しさん:03/06/17 11:16
電源が抜かれたときにもファイルが妥当にクローズされてるような例外ってどう書けばよいですか?
マシンにUPSつけるしかないだろ。
で、OS依存の例外をキャッチするとか

あるいは電圧監視プログラムをバックグラウンドで走らせて、
電圧落ちたら運がよければ例外スロー

75デフォルトの名無しさん:03/06/25 02:48
みんな例外に興味ないすか・・・
(´・ω・`)
76_:03/06/25 02:57
使える環境では日常的に使いすぎて、書き込むようなネタはない。
使えない環境は関係ないし。
例外オブジェクトの中にエラーメッセージを構築するための情報を
ぶちこむと思うんだけど、どんな感じで入れる?

例えばWindowsのAPIがエラーを返してきた場合だと
エラーが発生したAPIと、APIに渡した引数、APIが出すエラーコード、
APIを呼んだ箇所によっては特別な対処用メッセージ、などなど。

これらをさっくりぶちこんだ例外オブジェクトを構築するコードを
1,2行で書けるような仕組みを作れればいいんだけど…
if( えら? )
{
 std::ostringstream ss;
 // ぶちこむ
 throw えら( ss.str() );
}
exception 継承して what() でエラーを得てはダメなんでしょうか??
俺はふつうにそうやってるけど。なんで「ダメ」だと思うのさ?

あと「コード1,2行で」っていうけど、マクロ使えば何行だって大差ないし。
8280:03/06/27 21:20
>>81
変なことを聞いてすいませんでした。

ほとんどのサイトで自前のExceptionとか定義してそこから派生させていたので
<exception>は普通あまり使われないのかと思ったんです。
8378:03/07/01 03:39
>79-82
それはそれで正しいと思うんだけど、
「コンピュータに詳しくないエンドユーザーが、エラー発生時に
どういう対応すればよいのか分かるように。」
「ユーザーを小難しいメッセージで混乱させないように」
というようなことを言い出されるとこれがなかなかむつかしい。

try {
foo(argument);
}catch (SomeException& e) {
//この例外の場合は原因メッセージが必要
throw HogeException(HogeMessage + "(原因は" + e.what() + ")");
}catch (OtherException& e) {
//eの種類によってはe.what()はユーザーに見せたくない
//argumentは見せる必要がある。
throw FugaException(FugaMessage + argument);
}

なんてやってるとどんどんふくれあがってゆく。
84山崎 渉:03/07/15 10:32

 __∧_∧_
 |(  ^^ )| <寝るぽ(^^)
 |\⌒⌒⌒\
 \ |⌒⌒⌒~|         山崎渉
   ~ ̄ ̄ ̄ ̄
85山崎 渉:03/08/02 02:53
(^^)
86山崎 渉:03/08/15 17:58
    (⌒V⌒)
   │ ^ ^ │<これからも僕を応援して下さいね(^^)。
  ⊂|    |つ
   (_)(_)                      山崎パン
87デフォルトの名無しさん:03/09/13 14:01
BCBでは、exceptionでなくて、Exception使うべき?
>>87
Del厨は(#・∀・)カエレ!!
89デフォルトの名無しさん:03/09/23 23:04
HEWのC++でも、ちゃんと、catch動きますか?

やっぱ、__finallyは無いですよね?
90デフォルトの名無しさん:03/11/04 20:38
HEWってstd::runtime_error無いの?
91デフォルトの名無しさん:03/12/13 21:48
質問です。
数段の関数呼び出しをした中の処理でプログレスバーが出て、
ユーザーがキャンセルできる場合、
キャンセルを例外としてthrowするのは問題ないでしょうか?

現状、エラーは例外をthrowするけども、
キャンセルだけは戻り値(二値)になっているコードがあって、
処理の結果を返したいときに戻り値が使えなくてちょっと不便に思っています。
>>91
問題ない。
エラークラスを派生して、エラーコードメンバを足せば?
93デフォルトの名無しさん:03/12/16 07:10
C++でまともにバックトラック処理書く手段が例外飛ばししかないのがな。。
意味的に例外じゃないのに。
安全なlongjmpとか用意すべきだったと思わない?
>>93
バックトラックって,用意したスタックをロールバックするだけじゃない?
>>93
> 安全なlongjmpとか用意すべきだったと思わない?

それがexception。
96デフォルトの名無しさん:04/04/14 00:29
例外クラスをどういうときに作るべきかで迷う。

>>96
そりゃ、catchを分岐させる必要があるときでわ?
98デフォルトの名無しさん:04/06/15 18:49
処理系のエラーオブジェクトしかthrow出来ないと思ってたが、
char *の文字列なんてものthrow出来るんだね。
組み込みだと便利かな?
いちいち関数の戻り値見ながらエラーだったら呼び元にエラーを返してと
とぼとぼやるよりは例外投げたほうがストレートでいいじゃん。
デストラクタを適切に実装していれば途中のオートオブジェクトも
自動的に消えて元にもどるわけだし。

システムコールのエラーもエラーリターンなんで
面倒なことはやめて全部例外投げる。

ってのは乱暴?
> システムコールのエラーもエラーリターンなんで
> 面倒なことはやめて全部例外投げる。

意味わからん。
>>100
int read_e(int fd, char *buf, size_t nbyte)
{
 int r;
 if(-1 == (r = read(fd, buf, nbyte)))
  throw errno;
 return r;
}
>>101
throwでint投げるんだね。

intとchar *とどっちが良いのか迷ってまつ。
char *を投げる場合、スタックに取ったchar変数だとマズイんだろうね?

"error:〜"みたいにべた書きしとけば大丈夫?
>>103
staticで定義しとくとか
105100:04/06/17 00:52
>>101
ん?
「エラーリターンなんて面倒なことはやめて全部例外投げる」
ってことか。それなら納得。

でも、 throw errno; はあんまりだな。
systemcall_errorとか、専用の型を作って、
what()でstrerror()が出るようにするのがよさそう。
エラーオブジェクトってのは、通常のクラスで良いのかな?

エラーオブジェクトが関数のスコープ抜けたら消滅しても困るし、
上位でcatchされてスコープ抜けたらオブジェクトが消滅した方が良いし。。。
>>106
C++/Javaなら、例外の基底クラスがあるので、
そいつから継承したものにするのがマナー。

C++でthrowに渡したオブジェクトは、
必ずコピーされたものがcatchに渡されるので、
特別な寿命管理は必要ない。
>>107
なんと、HEWのC++には例外基底クラスも無ければ、STLも無い。

ついでに、char *に使えるのはどうなってるかも教えて。
ローカル変数のcharのポインタはやっぱダメ?
>>108
別にポインタ自体の入れ物はローカル変数でもいいが
その参照する文字列がプログラムスタック上に確保されるような場合は×
静的に領域を確保しておくか、例外を投げるときにnew、catchステートメントでdelete
JavaだとガベージコレクトされるからnewでもいいんだがC++だと明示的に
deleteしてやんないとね
110デフォルトの名無しさん:04/06/18 00:21
俺もHEW使ってるよ。
タスクAでtryの中に入ってるとき、タスクBに制御が移り、
その最中でthrowしたらタスクAのcatchでとらえられたのはびっくりした。
例外ってそんなもんなの?HEWだけ?

あと、GCCもそうかもしれんが、ファイルをまたがって例外が飛ぶ時、
RTTIをチェックしないといけないのが引っかかった。


ま、STLもそうだけど、HEWはいままで触ったなかでかなり悲惨な部類の環境だなぁ。
>>110
その動作は至って普通です。

throwって要は「例外オブジェクト」をスタックやレジスタにセットして大域ジャンプ
してるだけなわけで。
アセンブラの言語レベルの理解は別にいらないけどスタックやプログラムカウンタ
まわりの概念が解ってればそんなに難しくないと思う
>>110
>その最中でthrowしたらタスクAのcatchでとらえられたのはびっくりした。

こうなると困るんだっけ?
普通な気がするが。
>>110
>ま、STLもそうだけど、HEWはいままで触ったなかでかなり悲惨な部類の環境だなぁ。

SH使ってまつ。HEWよりマシで、価格がそう変わらない環境教えて下さい。
114デフォルトの名無しさん:04/06/21 22:43
>>111,>>112
それ本気で言ってる?そんなんなら、例外構文なんて使えねーだろ。

>>113
逆に、HEWより劣る環境をどんだけ知ってるんだい?
>>110
その実行環境で言うところの、タスクって一体何?
それがほとんどモジュールと同じで、
システム全体でシングルタスクスケジュールで動いているのなら、
そういうこともあるだろうけども…
>>115
ITRONの言うタスクはWinでいうスレッドのことでつ。

システム全体というか、機器全体で1つのEXEみたいなものですが、何か?
117デフォルトの名無しさん:04/06/22 22:32
実は、例外機構がどのように実装されているのか知らんのだが、(レジスタの値を退避させるらしいけど・・・)
それを保存するとこはどこなんでしょ?
HEWは例外機構を使う場合、例外を使うと明示的にコンパイラに指示する必要がありまして、
もし指示しなかった場合は__curr_stack_entry(だったか?)がリンクエラーになります。
つまり、ここに全ての場所の、例外の継続情報が保存されるんじゃないかと。
だからタスク間で勝手に例外がとんじゃったのかな?と考えてみた。
>>117
ローカル変数のdestructorを実行しないといけないので、
ローカル変数のあるブロックごと、tryブロックごとに、
スタック上に印をつけておいて、それを実行環境が巻き戻しながら、
必要な処置を行っていきます。つまりスタックの操作を行います。

__curr_stack_entryってのは、
その現在のブロックのスタックを返す関数でしょう。(たぶんアセンブラ記述の)
119デフォルトの名無しさん:04/06/24 19:46
ということは、try-catchをタスク毎に動作というかタスクに閉じたくても、
HEWはITRONのタスクを知ってるわけじゃないから、
それは不可能ってこと?????

OSとコンパイラとセットじゃないと実装出来ないということかなぁ。
ITRONじゃC++実装不可能ってことか。
T-KernelはOSのソースを統合してるから対応可能なんかな、、、
普通タスクごとにスタックは別だから、
なんか特別なことやってなければ、
例外処理でタスク間を移動することはない。

>>110はなんか勘違いしたが、
programのbugによる異常動作だと思う。
121デフォルトの名無しさん:04/06/25 09:51
thanx!>>120

実際HEWでthrow使っている人は居ますか?
「throw -1」なのか「throw "error: details〜"」みたいなのか、
それとも、エラークラス(HEWには無いかな)派生してるんでしょうか?
空の構造体投げればいいじゃないか
123デフォルトの名無しさん:04/06/25 10:10
みんな自前のライブラリ・フレームワークと
自前のアプリ作る場合の例外って
どのクラスから派生してるの?
runtime_errorとassertだな。logic_errorは使わない。
125デフォルトの名無しさん:04/06/25 10:21
>>122
なっとく。
エラークラスを作れない環境では、エラー構造体でcatchを分岐するわけね。
で、空じゃなくて、構造体のメンバーにエラーコードとかエラー文字列入れたり。
>>125
それ、エラークラス作れてるってことじゃないの。
127125:04/06/25 10:53
>>126
あ、そか。

>>107 に例外の基底クラスを派生がマナーだけど、
C++だとメモリ管理不要って書いてあるね。

で、
{
 if (false == hogehogeAPI() {
  THogeErrorClass HogeError;
  throw HogeError;
 }
}
て感じ?
>>126
RTTIがないとcatchで分岐できませんからねえ。
129127:04/06/25 12:57
で、クラスは空っぽで良いのかな。
class THogeErrorClass {};
使う側がそれでいいならいいよ。型が重要。

まあエラー原因文字くらい入れといた方が、
全部まとめて、

} catch (exception e) {
cerr << e.what() << endl;
exit(1);
}

出来て便利だけどね。
>>128
HEWなんかでも構造体にもRTTIあるんかなぁ。
こんなん書ける?
 try
 {
 }
 catch (stuct structhogehoge hogehoge)
 { }
 catch (stuct structhoge hoge)
 { }
 catch (...)
 { }
>>131
・言語仕様
ANSI/ISO規格に基づき、例外処理やテンプレート機能もサポートしています。
http://www.hitachi-hec.co.jp/seihin-k/h8ccon/h8ccon01.htm

だから大丈夫なはずだけど、規格完全適合とは書いてないから、
使っている人に聞いてね。

ちなみにHEWって実行環境じゃなくて、開発環境なんじゃないの?
>>132
そのサポートしています、ってのが怪しいんだな。
規格の適合しています、と書けないわけだし。
構造化例外はオプション設定で「Use try, throw and catch of C++」をチェックさせるという後ろ向きなサポート。
後ろ向きなサポートなのは、ちゃんとサポートできてないからなんでしょ。
catch(...)でも例外がキャッチできずにabortいっちゃう事があって困った。
結局、例外使うのやめたんだけど。

ま、こっち側のミスの可能性は捨てきれないんだけど・・・。俺一人でやってるわけじゃないし。
135デフォルトの名無しさん:04/06/28 19:35
>>134
え”ー。
構造化例外の良いところは複数人数で開発してても、正しいエラー処理が出来ることろでわ?
「構造化例外」と「C++における例外」って
Win32では明確に違うものなんだけど
ここで言ってるのは同じものなの?
構造化例外ってCの例外の事だろ?
C++例外はオブジェクト指向だし。
Cの例外というより、
WindowsとVC++独自のプラットフォーム/処理系依存の例外処理。
>>132のリンク先にはそんな情報は見当たらないから、
>>133(=>>135?)はC++例外と構造化例外がごっちゃになってるんじゃないの?
>>138
VCは関係無いんだけど、無知ですか?
まあまあ、C++例外と構造化例外の名前を間違えただけで、
制御構造はどっちも似てるし、この辺で元の議論へ。

構造化例外は例外オブジェクトなんて無いけど、throwみたいなもでしょ?
再入不可とかあったきがする
143デフォルトの名無しさん:04/07/03 12:08
海外の組込み系クラスライブラリで、
Embedded C++に拘らず、メリットがあるからテンプレート(Embeddedには無い)なんかは使ってます、
だけど、
安全のためにthrowは使いません、て書いてあった。

catchしてれば良いだけでわ。
組込み的にthrowはどうやばいんだ?





組込み技術者がやヴぁい、というオチダタリシテ
標準 C++ では、全ての例外が、logic_errorかruntime_errorのどちらかから派生するそうですね。
守るべきでしょうか。
クラスライブラリに依存しちゃうしかないんかな。
>>144
ライブラリなら、守ってたほうがありがたいと思う利用者が多いだろうな。

> クラスライブラリに依存しちゃうしかないんかな。
こっちは意味がわからん。
MFCとかVCLとかで定義されてる例外のことじゃないの
そういうクラスライブラリに依存しているコンポーネントなら、そっちから派生した方がいいかも。
でも、どっちがいいかは微妙だなー。

こういうふうに迷わないように、新しいライブラリを作るなら標準例外クラスから派生して欲しいな。
> 標準 C++ では、全ての例外が、
> logic_errorかruntime_errorのどちらかから派生するそうですね。
細かい突っ込みすると、class ios_base::failureは違うけどね。
class ios_base::failure: public exception
{
 [...]
};

> 守るべきでしょうか。
それって設計の問題なんで、こうすべきなんて答えは
ここで出てこないでしょう。あなたが導きださなければなりません。

まるで女のファッションみたいに、これって変かな?
なんてのと同じような感覚でこんな質問をするなら
もっとC++、さらにはプログラミングそのものの訓練が必要でしょう。
自分で設計上の結論を見出せないのですから。

などと突き放しては身もふたもないので、アドバイス。

たぶん、自分が用意しようとしている例外クラスがなんで必要なのか、
何をさせたいのかが見出せていないから、こういう質問になるのかと思います。

自問自答してみましょう。設計とは自問自答の繰り返しです。

> クラスライブラリに依存しちゃうしかないんかな。
んー、ちょっとわからんかった。ごめん。
>>144
> 守るべきでしょうか。

はい。
直接 exception から派生する奴はほかにもあるみたい。
bad_alloc
bad_cast
bad_exception
bad_typeid
libstdc++では、
$ egrep -r 'public exception' /usr/include/c++/3.3/*
/usr/include/c++/3.3/bits/ios_base.h: class failure : public exception
/usr/include/c++/3.3/exception: class bad_exception : public exception
/usr/include/c++/3.3/new: class bad_alloc : public exception
/usr/include/c++/3.3/stdexcept: class logic_error : public exception
/usr/include/c++/3.3/stdexcept: class runtime_error : public exception
/usr/include/c++/3.3/typeinfo: class bad_cast : public exception
/usr/include/c++/3.3/typeinfo: class bad_typeid : public exception
な感じ。
152デフォルトの名無しさん:04/07/12 11:48
直接 exception から派生する奴が増えるのは、まぁ致し方ないとしても、
基底クラスがExceptionになったり、を何とかして欲しい。
ショウガナイから使ってるが、組み込み系では使えない。
組み込み系ではthrowを無視するコンパイラやライブラリが多いから、問題が表面化して無いが。
>>152
> 基底クラスがExceptionになったり、を何とかして欲しい。
何を問題としているのかわかりません。
>>153
catchするのが面倒なんじゃないの
やっぱ、exceptionに文字の付加情報が無かったのが、別クラスが出来た理由かな。
C++言語的には無い方が良いが、使うときには例外クラスに文字かコードは必須。
>>155
「文字の付加情報」と、 std::exception::what() は違うの?
whatって中身詰まってないし
詰まってないというか自分で入れろと
そこでvirtual関数をオーバーライドですよって、
詰めないといけないのは頭の中身なんじゃあ…
>>157-159
おまえらちゃんと会話しろよ。
>>156
あれ、exceptionにwhat()あったっけ?
自分の認識では、logic_error、runtime_error、とかの派生で初めてアクセスで出来たような。。。
>>161
what() は exception で virtual 関数として定義されている。
runtime_error 等は what() の戻り値がコンストラクタの引数として渡せる。
あ、そうだよね。やっぱ生のexceptionでは文字列詰めれない。

で、VC++でexceptionの派生をしたけど、かなり大変だったぞ。
他コンパイラで通るかも分からないしめんどー。
>>163
何が大変だったの?
ふつうにオーバーライドするだけじゃダメってこと?
アフォには何でも大変。
類推機能なしの脳には何でも初体験。
>>164
whatを使うために、こんなんなってたぞ↓

class HogeError : public exception {
public:
explicit HogeError(const string& _S): exception(""), _Str(_S) {}
virtual ~HogeError(){}
virtual const char *what() const{return (_Str.c_str()); }
protected:
virtual void _Doraise() const {_RAISE(*this); }
private:
string _Str;
};

組み込みコンパイラとクロスのソースとして使うことを想定してて、
下位のエラークラス派生を行わずにexceptionを派生した模様。
なんか無駄に終わったっぽいが。
>>164
exception("")って通るのか?
_Doraise/_RAISEは何やってんの?

標準の環境だけ想定すれば、
class HogeError : public std::runtime_error
{
public: explicit HogeError(std::string const& s) : runtime_error(s) {}
};
これでおしまいなんだが。

まぁ環境がちょっと特殊っぽいな。
組み込みを想定すると、 runtime_error は使っちゃいけなくなるのか?
説明足りなかったが、組み込みコンパイラは、
throwはサポートするがエラー派生クラスどころかSTLから無い。
「using namespace std;」は書けないし、実はusing句もサポートせず。
169167:04/07/13 11:23
レス番間違えた。>>167>>166宛て。
class HogeError : public exception {
 std::string str;
public:
 explicit HogeError(const std::string& s) : str(s) {}
 virtual const char *what() const { return str.data(); }
};

これだけで良いじゃないか。
そーいや、what()の戻り値ってc_str()じゃなくてdata()なんだよね。
>>168
それはC++の問題でも、ましてやVC++の問題でもないと思うんだが。
>>171
つか、このスレは例外処理を使うときの話であって、おまいの方が擦れ違い。

”C++の問題でも、ましてやVC++の問題でもない”からどーだって言うんだ。
>>170
多分それの方が短くて良いんだろうが、その内容にしても書くの面倒でない?
自分の環境の問題がC++の問題であるかのような発言をした>>155が悪い。
>>173
runtime_error使った>>167のやつでも面倒だと思う?
>>171
はぁ?

>>163 で、VC++でexceptionの派生をしたけど、かなり大変だったぞ。

VC++(C++)でexceptionの派生クラスを作るのは「かなり大変」
という話題から派生してるだけだけど、どこに問題が?

>>166 whatを使うために、こんなんなってたぞ

ご丁寧に、自分で勝手に煩雑な書き方をしていただけというオチまでついてるし。
>>175
自分的には、1行であるべきだと思う。
class HogaType_exception : public exception {} ;
class HogeType_exception : public exception {} ;
と沢山作っといて、で、最上位でdynamic_castして分岐させて。



ところで176は邪魔だな。
複雑なソースがあるから、このスレで何とか解決しようと思ってるんだが、何度も絡んでくるな。
レスは要らないと言ってるのに、もうレスすんあ。
exceptionとstringってどっちが先にできたの?
初期の頃って両方無かったような気がしたんだけど気のせい?
>>177
一行で書きたけりゃ、宣言と定義をわけたり、マクロを使ったり、いろいろできるだろ。勝手にやればいい。
最上位でdynamic_castって、catch並べて分岐しちゃダメなの?

> レスは要らないと言ってるのに
電波か?
179はスルー
電波だな。
176> ご丁寧に、自分で勝手に煩雑な書き方をしていただけというオチまでついてるし。

177の要件を満たす開発環境なんてねーし、何と比較してるんだよ。
そもそも、exceptionがあってruntimer_errorが無い環境ってのが想像不可能。
class HogeError : public exception {
 std::string str;
public:
 explicit HogeError(const std::string& s) : str(s) {}
 virtual const char *what() const { return str.data(); }
};

これをマクロにして、組み込みコンパイラがコンパイルエラーなんか出したときにゃ、ガクブルだな。
C++は好きだけどライブラリの中は結構追いにくい。
組み込み電波は放置しろ。
電波を連呼するなんて初心者だな。
連呼した方が勝ちってわけでもないのに。
>>170
一般には間違い。
例外クラスのコピーコンストラクタは例外を投げてはいけないので、
例えばこんな感じでラップする必要がある。
class HogeError : public exception {
 boost::shared_ptr<std::string> str;
public:
 explicit HogeError(const std::string& s)
    : str(new std::string(s)) {}
 virtual const char *what() const { return str->data(); }
};
stringが参照カウントで実装されているような処理系に依存していいならOK。
意外にC++のライブラリの中の記述はスッキリしないね。

STLの中の人が頑張ってくれてる、という考え方もあるが。
>>186
そこまでするんじゃ、やっぱりruntime_errorを継承するべきだな。
exceptionがokで、runtime_errorがNGなケースが思いつかないよ。
>exceptionがokで、runtime_errorがNGなケースが思いつかないよ。
HEW環境。
>>186
bad_allocはその辺回避するためにwhat()がないんでしょうね。
>>190
定数文字列返せばいいだけじゃん。
>>190
あるよ。
やっぱ、static の文字列しか駄目なんだよね。
ローカルのchar[]は駄目なんだよね。
>>193
C/C++ではローカルのchar[]を戻り値にできないのはあたりまえ。
じゃ、ローカルの:stringならOK?
>>195
戻り値の型がstd::stringなら、どっちでもOK。
>>186
boostを使ったこと無いんですが、便利なんですか。
コンパイル通る環境はWin/POSIXくらいかな。
>>197
boostの中には様々なライブラリが入ってる。
使用できる環境もライブラリごとに違う。
一度使ってしまうと、使えない状況が苦痛になってしまうレベルのものが多い。
まるでヤク中だな。
つぎつぎと珍妙度の高いライブラリを
摂取していかざるを得ないなんて。
>>199
だれも「珍妙度が高い」とも「つぎつぎと摂取していかざるを得ない」とも言ってないわけだが。
電波か?
boostってドラフトの塊であって、いずれ纏まった形で標準ライブラリになるんだよね?
でないと困る。
まあ実装テクニックは珍妙度が高いと言わざるを得ないこともしばしば
>>201
そんな予定は無い
>>201
一部は標準ライブラリに含まれる予定。
全部ではない。
spiritが標準ライブラリに入ったらびっくり
206デフォルトの名無しさん:04/07/26 10:20
STLやnamespaceも怪しい組み込み環境にboostなんてありえないな
>>206
boost::preprocessorならOKだよ。
208デフォルトの名無しさん:04/07/26 15:02
やはり例外処理にはNestableExceptionが必須でしょ。

例外をListやVectorに蓄積する必要もなくなってかなりええねえ。

org.apache.commons.lang.exception.NestableException
http://www.jajakarta.org/commons/lang-2.0/ja/withoutPrimary/org/apache/commons/lang/exception/NestableException.html

org.apache.commons.lang.exception.NestableRuntimeException
http://www.jajakarta.org/commons/lang-2.0/ja/withoutPrimary/org/apache/commons/lang/exception/NestableRuntimeException.html

 ま た C# の パ ク リ で す か 
>>208
せっかくだから最近の Windows にあるような Vectored Exception Handling も
あると良いのだけれども。オープンソースの世界だと需要がないのかな。
C#がjavaのコピーなんだからおあいこだべ
212デフォルトの名無しさん:04/09/06 09:46
マルチスレッドでcatchしなかった場合、メインスレッドのcatchに通知されますか?

同様に、ITRONのタスクでthrowしてそのタスクでcatchしなかった場合、メインタスクのcatchにジャンプするんでしょうか?
213デフォルトの名無しさん:04/09/12 02:59:36
nnnawakya-ne-daro
214デフォルトの名無しさん:04/09/12 03:00:57
組み込み系って、うんこンパイラだから例外処理自体まともにうごかないってことはないの?
215デフォルトの名無しさん:04/09/12 06:44:52
>>212
両方とも「しない」
216デフォルトの名無しさん:04/10/27 01:41:57
ほしゅ
217デフォルトの名無しさん:04/11/18 13:41:13
組み込み系な人たちにthrow/catchを教えるためのサイトを教えて下さいでつ。

cppファイル郡にcソースを平気で入れたり、コピペ・コーディング、といった程度でなく、
ソースファイルのコピー利用やプロトタイプ宣言をcソースに記述が平気な人たちが、
戻り値は駄目だ!これからはthrowだ!、という思いになるような説明キボン
218デフォルトの名無しさん:04/11/19 00:28:27
219デフォルトの名無しさん:04/11/19 01:09:07
>>217
標準ライブラリをリンクできない環境とかで、
例外処理ルーチンを自分で書ければ例外使えるんだけど、なんとかならん?
220デフォルトの名無しさん:04/11/19 09:42:23
>>218
マニアックだね
221デフォルトの名無しさん