1 :
デフォルトの名無しさん :
2006/03/18(土) 16:37:26 語れ
断る!
まぁ、そう言わずに。
Cはこれがないから辛い。 Enum系含んだ構造体で値返せばいいの?
5 :
http://www.vector.co.jp/soft/win95/util/se072729.html :2006/03/18(土) 18:02:48
TextSSの64bit化ってできない?
例外の使い方(文法のことではなくて)を解説しているページないですか?
おれも知りたい。 こういうところでは、こういう例外処理を入れたほうがいいよ、 みたいな情報が欲しい。
8 :
デフォルトの名無しさん :2006/03/18(土) 21:18:17
ぬるぽ!
何かが起きそうな予感がする所にはエラー番号を表示するコードを忍ばせておく
11 :
デフォルトの名無しさん :2006/03/18(土) 22:37:00
その「何かが起きそうな予感」ってのを、 詳しく。
12 :
デフォルトの名無しさん :2006/03/18(土) 23:14:54
>>4 例外種類をのなら、その構造体でも行けるかもしれないけど
スタックの巻き戻しも無い・再throwも無い・・・
なので、例外の恩恵に与るには程遠い
Cではsetjump 〜 longjumpが代わりになると言えなくも無い。 そしてVCやBCCなら構造化例外処理がある。
何かが起きそうな予感がする所には盗聴器を忍ばせておく
C++つかっときゃいいんじゃね? CEの開発だとC++だけどthrowが無いとか聞いたけど。
16 :
デフォルトの名無しさん :2006/03/19(日) 00:41:22
俺は最近よく使うが、コード量はかなり減った気は するなあ。 もう関数呼ぶたびに戻り値のチェックなんてしたくない な
17 :
デフォルトの名無しさん :2006/03/19(日) 00:50:51
例外を、単なる別のエラー処理技法のように扱ってはいけません。 エラー コードを返したり、グローバル変数の設定したりすることと 同レベルだと思ってはいけません。例外は、それを取り巻くコードの 構造と意味を、根底から覆します。例外は、プログラムの実行時 セマンティックを一時的に繋ぎ変え、通常実行しているコードを迂回し、 こういう状況でなければ決して実行されないコードを動作させます。 例外は、エラー状態を認知させ、プログラムの死という罰則を用いて その状態を改めようとします。 このように、例外には単純なエラー処理を超えた特性があります。 これらの特性を必要としない、理解しない、あるいは文書化したく ないなら、例外をスローしてはいけません。 例外以外のエラー処理技法を探してください。
19 :
デフォルトの名無しさん :2006/03/19(日) 00:53:24
C++の例外って、同じプラットホームでも コンパイラによって実装が違ったりするの? そーゆー違いについて書いてるページとか無いですか?
20 :
デフォルトの名無しさん :2006/03/19(日) 01:00:55
>17 そうか?それはJavaの例外は否定ということか? 問題はエラーとか例外の定義だよな これは人よってとらえ方が違うからな。 そしてこれは関数一つ一つに細かく考えなきゃ いけないからまたたちが悪い。 例えばファイルの削除に失敗した場合はどっち? OreSocket::Sendに失敗した場合はどっち? とかさ
>>19 たとえばVCの例外機構はWindowsのOS機能として用意されている
SEH(構造化例外処理)の上に構築されていて、
UNIX系OSではSEGVで停止するようなHW例外も捕捉できる。
Mingwのcatchではこういうことはできない。
(ただしMingwにはSEH対応パッチみたいなものは存在している。)
自分の関数内で始末できないエラーを例外として投げて、 ガリガリっとスタックを(半ば無理矢理)巻き戻していく というのが俺の認識だな 直前の関数で catch されるなら戻り値でエラーを返すのとほぼ一緒だけど、 コールスタックを2段以上一気に巻き戻せるのが特徴的に見える しかしこいつの天変地異的な効果のせいで プログラムが不必要にややこしくなった気もしないでもない
23 :
デフォルトの名無しさん :2006/03/19(日) 01:29:07
あと無名オブジェクトのデストラクタの2回呼び出しとかも gcc,vcで結構違うな
予期されないエラー状態を例外でいいよ。 EOFを認める。
25 :
デフォルトの名無しさん :2006/03/19(日) 01:36:22
だから「予期されないエラー」の定義が難しいって ことだろ?
>>27 途中までコンストラクタ、デストラクタからのスローについて誤認したまま語ってるので注意。
まぁ古い記事だからしょうがないだろう。
あと、例外仕様についての記述も時代遅れかな。 C++ では throw() 以外使わないのがお勧め。
>>29 throw() 以外って、何か他にあったっけ?
例外を使うと決めたら、例外に対応したコードを書き、徹底的に例外を使うべし。 中途半端に、例外を使うコードと、使わないコードを混在させるな。
でもさー 他人が投げる例外って、色んな例外の形式が混在して、嫌じゃない?
それだけならまだいいが、ポインタ投げる奴とか、ヒープオブジェクト投げる奴とか・・・ C++での話でつ。
でも例外使わないと危険なんでしょ?
38 :
デフォルトの名無しさん :2006/03/19(日) 18:04:05
>35 ...で捕らえてればいいでしょ、とりあえず。ドキュメントが しっかりしてるのはそれを捕まえればいいし。 >37 まね。例外なんてつかわねー、なんて言ってらんないしね。 stlもcastもnewも例外投げてくるし。 とにかくリソースを確保したりする箇所では、catchしないと だめだめだね
例外をこまめにcatchしてたら、 関数の返り値でエラーを返して、呼び出し側でチェックするのと、変らないじゃないですか。 例外をcatchするだけでは、何かエラーが起きて処理を中断したことしか、わからないじゃないですか。 エラー内容を表示したり、ログに記録したり、そういったことをするためには、ただcatchするだけじゃぁ・・・。 理想を言えば、 たとえば、インタラクティブな操作がないコマンドラインで動くプログラムなら、 try〜catchは、main関数ただ一ヶ所に書いて済むようにしないと。
40 :
デフォルトの名無しさん :2006/03/19(日) 19:47:49
>例外をこまめにcatchしてたら うーんとね、こまめにするかどうかは自分が書くコードによるよ。 例えばさ A* a = new A; a->f(); ← 1 *a = "test"; ← 2 delete a; 1で例外きたらまずいでしょ。2の演算子だって例外を投げるかも しれないでしょ。例外はどこからでも飛んでくることを想定して なきゃいけないんだよ。だからなるべく、メモリを確保するとか DBに繋げるとかリソースを確保する関係のコードとか、この区間で 例外が来たらまずいというコード量を少なくすることが必要なの。 それが例外セーフなソースを書くということで、その辺のことが 上記の偉い人たちが書いた本に書いてるから読んでみ
41 :
デフォルトの名無しさん :2006/03/19(日) 19:55:09
rewind書くのも面倒くさい
>>40 mallocやnewをカプセル化しないのが悪い。
例外を使うと決めたら、上手に使わないといけないんですよ。 人によくSTLを直に使わないのはどうして? と聞かれるけど、 例外をthrowするから と答えると、try〜catchすればいいとか言われる。
だからそういうことがエロイ人の本に書いてんだろ
>>36 エラーコードのint型を投げる奴とか、エラーメッセージのchar*型投げる奴とか・・・
なんでC++はスタック上の std::exception 以外投げられないように設計しなかったのか小一時間・・・
47 :
46 :2006/03/19(日) 21:22:46
あー、しかもchar*型投げるサンプルソース載せて、便利ですねーなんて抜かしてる入門本もあるからなぁ・・・ なんでこんなにレベルの低い本が平然と流通するのかねぇ・・・
48 :
46 :2006/03/19(日) 21:26:12
あー、一番ヌッ殺してやろうかと思った奴は、__LINE__を投げつけてきた奴もいたなぁ・・・
>>48 >一番ヌッ殺してやろうかと思った奴は、__LINE__を投げつけてきた奴
assertと勘違いしている悪寒。
>>46 なんでもありなのがC++ですから。
>>47 それは同感。
せめてstd::exceptionくらい載せろよと思う。
>>48 __LINE__だけじゃぁなぁ。
__FILE__も一緒に投げてもらわないと。
例外飛んでくるのを特段catchもせず、放置してたら どうなりますか?
>>52 基本的にプログラムが終了する。
終了する前に何するかは言語による。
>40 そういう問題じゃないんだよ・・
55 :
デフォルトの名無しさん :2006/03/23(木) 23:40:12
hoge
今日、2年前から好きだったコンビニの店員の女の子に 思い切って告白したら例外処理された、、、
>>56 例外処理されるだけありがたいと思えよ。例外処理されるようなお前はその子にとっては特別な存在だと思うぜ。
俺なんてうまく処理された振りをされて騙されたぜ...彼女バグ持ちだったんだ...
例外ならぬ恋愛
>>57 きっとお前が「エラーが出ないようにしろ」タイプで
彼女は「出ないようにしました」タイプだったのさ
60 :
デフォルトの名無しさん :2006/03/24(金) 14:17:12
>>59 いや違うんだ。彼女はそうかもしれんけど、俺はダメならダメって言って欲しいんだ。
それなら早く諦められるから。
C++の設計と進化でも読んで、なぜC++に例外処理が付け加えられたか 理解しろ。話はそれからだ。
>>51 throw __LINE__
throw __FILE__
っがだめってこと?
C++ に限定して言えば,例外処理って 究極的には「いかに try-catch を書かずに済ませるか」だと思う.
std::exceptionを投げると 何かいいことあるの?
>>65 宝くじに当たるわ
彼女が出来るわ
でいいことずくめ
May 14, 1998 朝起きたら、背中だけでなく足にも腫物ができてやがった。 犬どものオリがやけに静かなんで、足引きずって見に行ったら数が全然たりねえ。 めしを三日抜いたくらいで逃げやがって。 おえら方に見つかったら大変だ。 May 16, 1998 昨日、この屋しきから逃げ出そうとした研究いんが一人、射さつされた、て はなしだ。 夜、からだ中 あついかゆい。 胸のはれ物 かきむしたら 肉がくさり落ちやがた。 いったいおれ どうな て May 19, 1998 やと ねつ ひいた も とてもかゆい 今日 はらへったの、いぬ のエサ くう May 21, 1998 昨日PSPをもらってからすっかり体調も良くなった。 さらに職場で気になっていたあの娘から今晩デートに誘われた。 昇進も決まったし、今最高の気分です。 投げてよかった std::exception
それ、何てバイオハザード?
>>65 std::exceptionというよりも、その派生クラスを投げておけば、
例外を受け取る方はstd::exceptionだけを受け取れば済む。
>>64 1行毎にtry〜catchで囲んでいて、
だったら返り値でやれよ!!!
と言いたくなるようなソースを見たことがある。
実際に言ったら、エラーを例外ではなく返り値で返すラッパーを作って使うようになった。
71 :
デフォルトの名無しさん :2006/03/28(火) 23:07:12
>>64 うーーむ。
奥が深い。
正にその通り。。
MFC/ATLが投げる例外がstd::exception派生でないのが地味に面倒くさい。 ATLは変えられるけど、プロジェクト作る度に設定するのが面倒くさい。
73 :
61 :2006/03/29(水) 00:04:35
>>62 レスありがとうございます。
「C++の設計と進化」はすでに読み終ってます。
感想としては先に「ARM」のほうを読んでいたため、例外処理の部分はあまり参考になりませんでした。
ARMとD&Eは性格が全く違うし、そんな参考にならないというほど話がかぶっていた覚えは無いが。
汎用的に書くとtryもcatchもできなくなる 究極的でなくても最近のアプリはウィンドウクラスすらtemplateになっている 例外はエンドユーザのためのインターフェースじゃないのかと
76 :
デフォルトの名無しさん :2006/03/29(水) 05:05:30
おれは、gotoで、エラー処理、してる。完璧。
>>75 いや,汎用コンポーネントでも try-catch は使うべきところでは
普通に使うと思いますよ.
汎用コンポーネントの場合, "exception neutral"(例外中立)もしくは
"exception transparent"(例外透明)という概念が重要になると思います.
これらの概念に対向する概念として "exception translation" というのが
ありますけれど,これもコンセプトに例外仕様が明記されるような
汎用コンポーネントでは,使用されても特に問題はないように思います.
int func(){ int ret = 0; try{ if(!func1())throw 1; if(!func2())throw 2; if(!func3())throw 3; ... }catch(int e){ ret = e } ... // 開放処理 return ret; } な使い方じゃ駄目?
駅で階段見上げたら女子中学生がいてさ、スカートの中見ちゃったんだよ。 そんでその女子中学生にいきなり振り向かれて 「せ、責任とってお嫁に貰ってください・・・」 って言われちゃったんだ。 俺は慌てちゃってさ 「・・え?は、はぁ・・・」 みたいに返してそのまま通り過ぎようとしたら 俺のシャツをチョコンと指で掴んでずっとついてくるのね。 そんでとうとう家までついて来ちゃってさ 「はじめてですけど覚悟は出来てます・・・」 とか言うわけよ。 俺もう理性が吹っ飛んじゃって (全てを読むにはstd::exceptionを投げてください)
throw unexpected_exception();
} catch( ... ) { std::exception ex; throw ex; }
>>82 別に例外を使う必要がないコードじゃない?
84 :
デフォルトの名無しさん :2006/03/29(水) 18:36:36
>>46-48 あたりの__LINE__なげちゃだめとかint投げちゃだめって何で?
throw MyException( __LINE__, __FILE__ );
って俺やってんだけどこれってだめなの?
それはMyExceptionを投げてるだろ。
86 :
84 :2006/03/29(水) 19:36:41
ぁぁ。OK ごめん。C++の前に日本語勉強するわ。
std::exception しか投げられないと void find_(tree *t, int key) { if (t->val == key) throw t; else if (!t->left) find_(t->left, key); else if (!t->right) find_(t->right, key); } みたいなコードが書けなくて困るだろ。
ほんとに書き捨てのコードならそれでも構わないが、 一般的に例外の throw と catch でもって値のやりとりをするのはよろしくない 実装にもよるが、大抵の場合かなり遅い 以前、例外で値を返すフィボナッチを作って g++ でコンパイルして走らせてみたが、 笑えるくらい遅かった
>>88 87 は禿本で良い書き方といわれてることを知ったうえでの発言だろうな?
何で87はtree*返すようにせずに、voidにした上で例外なんか使うの?
91 :
88 :2006/03/29(水) 22:05:00
>>89 禿本に書かれてようが何だろうが、
少なくともこの例に限っては戻り値で返す方が良いスタイルだと俺は思うけど?
消 極 的 に な っ て き ま し た
「見つかったら返す」 ことがソースコードから明らかになるから。 戻り値をNULLと比較するのはNULLがノードなしに対応していることを知らないといけない。
正常系で例外を投げるのは良くないと思います。
>>82 所謂、最低な例外の使い方の一つ
>>94 激同
正常系で例外を投げてる時点で、例外使う資格無し
Javaを使ってみて、 例外を投げる可能性があるのかどうかハッキリする というのは、C++にも欲しい機能だと思う。 C++では、どんな例外が上がってくるのか、さっぱりわかんないんだもの。
>>98 C# がその機能を破棄したのは何故か、知っておくといい。
>>98 「例外を投げる可能性があるのかどうか」だけなら
throw() の有る無しでハッキリするよ。
きっちり使ったほうがいいんだろうけど、あんまり付けてないな。
デストラクタとか全部付けなきゃいけなくなってメンドクサイ。
自分が投げる例外だけでなく、 自分が呼んだ関数の先で投げたのがスルーされて自分に飛んでくるのも含めて、 膨大になり杉。
>>101 とりあえず、自分から呼び出した先での例外は、すべてcatchすれば、、、
やっとれんわな。
例外仕様はテンプレートと激しく食い合わせが悪いからな。
例外のコンストラクタにSystem.exit()を仕込ませるんだ!
他人が投げた例外は識別をあきらめて一つに扱うってことになる。
107 :
106 :2006/03/31(金) 20:01:37
>>105 まあ、なんだか分からんけど、成功してないのは確か、までは分かるしな。
109 :
デフォルトの名無しさん :2006/03/32(土) 00:26:54
C++ Coding Standards 75.例外仕様を避ける
>>112 それって、関数にどんな例外を投げるかちゃんと指定しろって事だろ。
どんな例外を投げるか決めてしまったら、それ以外を投げられなくなってしまう(バージョン問題) ということは、つまり バージョンが上がれば、想定していないような例外が上がってくる可能性がある ということなわけで、つまり 例外の識別は諦めろ ってことなんだな。
class MyException extends RuntimeException {} って不味い手かな?
>>87 の例って、以外と大域ジャンプが一番実装が簡単になるな。
戻り値だとああすっきりと書けない。
>>116 時と場合によるかと
MyException がRuntime errorを表わすのなら大蟻
>どんな例外を投げるか決めてしまったら、それ以外を投げられなくなってしまう(バージョン問題) 基底クラスで指定しとけばいいんじゃねえの? 派生させて投げられるジャン?
>>119 浅はかなり。
それだと意味がわからないぐらい抽象的な指定しかできなくなる。
または無茶な継承を容認せざるを得なくなる。
while(true){ Func(); } を抜けるのに、例外使っちゃだめ? たとえば、Funcで、非同期recvしてて、ユーザーがExitボタン押した場合とか。
Funcの戻り値で判定できないのか?
123 :
:2006/04/08(土) 01:38:46
ぁー実際は while( 1 ) { Dispatch(); } って感じで、状況によって違う関数を常に送出してます。 最初はifで判定して、ループを抜けてたんですが、 try { while()... } catch( MyException &E ) { if( E.code() == USER_EXIT ){ status = SUCCESS; } else{ status = ERROR } } みたいなコードの方が綺麗かな。と思いまして。 ただ、正常系で例外使うなって話があったんで、だめかなぁと。。。
>>123 「正常系で例外を使うな」なんて指標にすぎないんだから、
使ったほうが綺麗にかけるならどんどん書くべき。ただしコメントは必須。
>>123 確実に「なんでこうしたの?」って聞かれるだろうな。
例外はオーバーヘッド増えるよ。
横からすんません。 具体的なオーバーヘッドってどんなものなんですか?
例外の実装方法による。
129 :
123 :2006/04/08(土) 14:07:35
んー。やっぱりifで判定すべきですかね・・・
例外処理はコンパイラが最適化する価値をあまり見いだしてないという側面もあるな そもそも最適化かけるには面倒な条件が多いし、あまり頻繁に起こらない部分に 最適化をかけても意味がないというのもある
とにかくって・・・これは酷い・・・ この程度の認識でオーバーヘッドだコストだと言っているとは。 リスクを減らすために言語レベルでの質の高い安全策を使うのだから リスクの残る糞自前コードを使うよりオーバーヘッドがあるのは当然のことだ。
なんかしらんがC++使う連中はパフォーマンスにこだわるやつ多いよな
>>123 個人的には
>>17 を読んでねとしかいえない。
>>131 例外はどういうふうに処理されるのでしょうか?
参考にさせていただきたいので書籍やサイトをご教示ください。
書籍は「Advanced Windows」以外の本でお願いします。
135 :
123 :2006/04/08(土) 15:43:11
例外は本当に例外な時にしか使うなってことですよね。 でも私はスマートに書ける場面なら、例外を使ってもいいと思うんです。 なので皆さんの意見を聞きたかったのですが。 とりあえず我流でいきますー。
>>135 人の意見を取り入れる気がないなら聞くな
137 :
133 :2006/04/08(土) 16:27:38
>>134 なるほど、アセンブリを読むんですね。
longjmpで検索してみたら、いろいろ出てきたので調べてみます。
教えてくださりありがとうございました。
138 :
デフォルトの名無しさん :2006/04/08(土) 21:16:47
クラスAでクラスBのインスタンスを生成してて、 クラスBがクラスCのインスタンスを生成している場合、 クラスCの実行時例外はクラスBでキャッチするの?
>throw文の明白な使用は,普通なら負の値を期待しないところで整数値-1のような予期しない値を返し, >エラー条件を処理する古風な方式の代替手段を提供する。経験的に,その予期しない値は,呼出し元で >無視されるか又は検査されないことが多いことが知られており,頑健的でない若しくは望ましくない振る舞い >又はその両方をプログラムにもたらす。 例外の強力なところは 例外時の処理の実装の必要性を意識させるってことだろ? try〜catchを使えばコードが必ず見やすくなるというものではないし、 try〜catchでもcatchしわすれた例外があれば 実行時に落ちてプログラム自体が終了してしまうし
元請け側でデフォ処理書いとけば下請け側がキャッチしなくても エラー処理ができる。例外のメリットはそれだけだろ? 下請け側で頻繁にtry〜catchするのが前提の関数書くくらいなら返値でおk
std::bad_allocを上のほうで捕まえてるんですが、発生させた場所とか、 スタックトレースのようなものを、ログに取りたいんですが、どうすればいいんでしょうか?
発生した場所でログを書けば?
じゃあいちいちnewした直後にcatchして、ログ書いて、throwし直すんですか?
operator new をオーバーライドするか、いちいちcatchする
146 :
デフォルトの名無しさん :2006/04/11(火) 05:36:51
VCの場合オーバーヘッドは例外ハンドラの設定と解除だけだと思い込んでいますが、 他にどのようなものがありますか。
>>146 ハンドラチェインのまき戻りだけでえらい時間が掛りますよ
> ハンドラチェインのまき戻り 例外が発生した時に、その例外を扱うハンドラを探す処理の事でしょうか。
C++なんですけど、 なんでthrow 123;とか throw "string"; が駄目なんですか?
例外を捕捉する中の人のことも考えてあげて下さい
>>150 まったく意味がわからないんです。
今までにもintを投げるなという議論は見かけたのですが、
具体的理由が書かれてなくてわからないんです。
死んでるスタックを参照するからですか?
言語的には何も問題は無い。 使い勝手の問題。
では、48が言ってる__LINE__投げた奴殺すというのは、 使い勝手が悪い。ということなのでしょうか? てっきりスタックが絡んできてでんでんだと思ってたのですが、、
数値だけじゃ例外の内容がわからんのんよ
>>151 あるライブラリは「問題の発生したソースコード内の行番号を int で throw します」という
仕様だったとする。使う側は catch(int line) などで補足することになるだろう。
もうひとつのライブラリは「errno と同様の値を int で throw します」という仕様だったとする。
この二つのライブラリを同時に使おうとすると、 catch(int line) と catch(int error)
ってことになってエラーになる。
ソースコード内の行番号をエラーメッセージに出すのも、いい考えだとは思わない。
ぁーなるほど・・・ 理解できました。別にスタックが絡んでくるわけじゃなかったんですね。 ありがとうございました。
>>149 何でもいいからクラスに包んで投げれば、受け取る側も選別しやすいっしょ?
漏れの作った漏れ専用ライブラリはconst char *を投げるぜ。 エラーの内容はcatch側で勝手に解析関数呼べって素敵仕様さ。 #つーか、どうせmain()でその内容表示してreturnするだけだがな。
>>158 std::exceptionから派生させようぜ。
what()を書くだけで済むから。
std::exceptionの使い勝手が悪いと思う人挙手
WaTってあれだろ?
↑で議論されてることってみんなどうやって勉強したの? おすすめの教科書あったら教えてください!
163 :
146 :2006/04/17(月) 14:05:21
本当に有意なオーバーヘッドがあるんでしょうか。教えてください。
>>163 速度は実測が基本。
ましてや例外処理については実装による差が大きいので、実測しかない。
python のイテレータ終了が raise StopIteration だということを知って C++ 使いの僕はひどく驚いた。
try書くの省略できないかねえ。ネストの階層が深くなるのがうざいのだ。 D&Eにもtryって別に要らないんだけど格好付けのために一応やっとくか みたいな事書いてあった気がする。
>>167 しかしそうすると catch の対象を示せなくならね?
漏れは try の中で生成したインスタンスを try の外で
使いたい、というおかしなコードを書いてしまって、
右往左往した経験がある。
169 :
デフォルトの名無しさん :2006/04/27(木) 23:30:33
newやハンドルとか絡んでる場合、開放とか考えると
>>78 がベター?
それとも、もっと良い書き方あるんでしょうか?
ポインタはスマートポインタに、ハンドルもラッパクラスに入れて解放はデストラクタに任せる。 いつどこで例外が起きてもリークが起きないようにしている。俺は。
Javaの例外処理の初心者をここへ誘導しちゃったけど良かった?
172 :
デフォルトの名無しさん :2006/04/28(金) 12:23:40
例外処理だけで一冊本が書けますね
何て本?
一つ挙げればExceptional C++
>>175 間違えてEffective C++
買っちまいそうだな。
コレと間違えてEfficent C++
買ってたからなw
俺なんか間違って Elotic C++ 買っちまって、家で開封して気づいたぐらいだからな
>177 おまいは俺の知人かw
C++では超が付く定番書だから間違えてでも買って読んどけ
俺は同僚のインド人から Ethnic C++ もらったぜ
俺は知り合いの二軍野球選手からEastern C++を
俺は上司のHiromi GoからExotic C++を2億4千万冊貰た
じゃあ私はExclusive C++を書く
後輩からEnbugged C++を押し付けられました。。。orz
俺は exciting C++ でいつも汗水たらしてる
Excuse C++が得意です
オブジェクト アンワインディングが必要な関数内で __try を使用できません。 ってエラーがでたんだけれども、これどういうこと? これ以外にも 非標準の拡張機能が使用されています : 'MyClass::hoge' は SEH と デストラクタ を含む 'str' 使われています。 って怒られた。もうわけわかめ。 alloca使った後でSTATUS_STACK_OVERFLOWを捕まえたいだけなのに・・・
エスパーかもん
Javaのthrows句ってめんどいよ。 コンパイラの仕事を人間さまにやらせてるって感じ。 C#は書かないでも勝手にthrowしてくれるからよいね。
え?w
>>193 レスありがとう。デストラクタがあるとまずいのか。
Warningのほう(非標準云々)見て大丈夫なのかと思ったけど違うのね。
SEHは言語を意識したものではないからなのかな?
とりあえず3Dモデリング関連で可変長のバッファを
チョコチョコ取りたいから後者を試してみるよ。
静的に確保したバッファーから割り当てる関数を
書く自信がないせいでもあるんだけどorz
structured_exceptionから派生させたクラスの実装を書くのがかったるくて FirefoxのnsISupportsばりの#defineを1時間弱かけて書いたんだけど、 >テンプレート ベースのパターンを代わりに採用すれば、 >ここで示した継承パターン放棄してもかまいません。 はよ言わんかーー!!
ヒープやフリーストアではダメな理由を30字以内で書きなさい
大人の都合
しゅみ
199 :
デフォルトの名無しさん :2006/05/21(日) 15:43:34
なるべく例外投げさせてそれから処理をするべきか、 それとも、 できるだけ例外投げてこないようにデータを前もってチェックするべきか 思想はどちらが良いのですか?
例えばファイルを扱うコンテナがファイルが無いぐらいで例外投げる、 なんてありえない発想だ。そんなの例外でもなんでもない。 ファイルは無くて当たり前、なのだ。 ただし、そのファイルがプログラムの継続にどうしても必要なDBだったとか、 の場合だと話は違ってくる。つまりそのコンテナを使ってる”側”のことだ。
>>199 俺の場合は、そもそもチェックや例外が極力必要ないようなデータ定義にすることに注力する。
チェックや例外が必要であればあるほど、その分プログラムは肥大化しバグも増えれば開発・メンテの工数も増える。
>>200 のような例はいろいろな論文や書籍で見かけるけど、誤解を招きやすいよな。
「ファイルなんて誰かが消してるかもしれないし、ないかもしれないだろう?だから、それは例外じゃないんだ」っていう言い回しは
「例外」という単語を「想定外」という意味で捕らえすぎている日本人には誤解されやすい。
「ああ、じゃあエラーはエラーでも、はじめから起こり得ると分かっているエラーなら例外は使うべきじゃないんだな」
なんてトンチンカンな論理に繋がっちまう人が多すぎ。(うちの社内研修でも)
どんなエラーだってプログラマが想定した上でエラーコードなり例外をスローするわけで、
本当にプログラマの想定外のエラーなら、例外すら投げられずプログラムが強制終了するだけ。
起こりうるかどうか、ではなくて、「プログラムの実行に支障を来すエラーなのかどうか」で区別すべきなんだが…
そういうのをうまく説明する方法はないものなのか。
例えば初期状態でファイルがないのはファイルを作ればいいが、途中でファイルがなくなるのはエラー処理して終了。 なんてアプリケーションなら後者は例外だな。
初心者が一番戸惑い易いのは、正常、エラーという状態の他に、あたかも “例外”という特殊な状況が存在するかのように錯覚してしまうこと・・・だと思う。 あくまでエラーハンドリングの手法の一つであることを強調すべきだなぁ
ユーザーのミスは入力チェック、 システム的なエラーは例外。 基本はこれでしょ。
ユーザのミスがリカバリ不可なら例外投げる。
>>207 おお、まさにその内容ですな(´Д`)
今度ペーパーにして配るわ。トンクス。
日本語訳は直訳に近くてよくわからんな…
なんか偉そうに垂れてる御仁が一番わかってないような。。 あのさあ、例外を「投げる」側のコードを書いている人間と、 そのコードを呼び出す側のコードを書いてる人間が同じだって前提に 無意識に立ってるからそういうトンチンカンな認識になるんだよw 例外の目的は、言ってみればフェイルセーフでしょ。 フールプルーフだよ。
202っぽい
流れが読めない。
意見が対立してるわけじゃないように見えるんだが、
なぜ
>>211 は煽り気味なのか?
だれかまとめてくれ。
言わんとするところは同じに見える罠
他人が使うライブラリの場合、引数間違いなんかはassertでもかまわん、と言うか、 assertってそういうときに使うもんだよな。 これが例外だとなんか気持ち悪い。
実行環境でも対応しようと思ったらって話になるんでね?
221 :
218 :2006/05/25(木) 00:17:30
>>217 ,220
「assertでもかまわん」というのは、「ノーチェック(もしくは即死)でもかまわん」ってことだよな?
んで、「他人が使う」ってことはリリースされてるってことだろ?
リリースされてるからには引数間違いなんかは十分起こりうるわけで、
それをノーチェックや即死にしていいの?
リリースするものをデバッグビルドで出すのか?
引数に対してassertか例外かは結局ケースバイケースだと思う。
開発中にとりあえずのチェックを入れる場合はassertかな デバッガで止まってくれるし リリース時にも残しておく、普通のチェックには例外使う
>>221 ATL/WTLやMFCのようなassertの使い方はダメだと申すのか?
220 の他人は 共同作業者 221 の他人は アプリユーザー
よほどTime-criticalな処理じゃない限りはassertの代わりに例外使ってもいいと思うが
仕様に違反した使い方したときはassertで引っかかってくれた方が嬉しいけどなあ。
assertでも例外でもデバッガが検出してくれるようにできるから、 ライブラリを作るやつは好きにしてくれと俺は思う。
assertは、プログラミングのミスを検出するのに使うのだろう。 InvalidArgumentとかをcatchして、ユーザーにはなんか深刻なエラーがでたような メッセージに偽装して表示してるコードは見たことあるな。
publicなメソッドの変な引数を注意するのには特に向いていない。>assert
Winアプリで、ウィンドウクラス登録やメインウィンドウ作成に失敗したときは例外?エラー処理?
>>232 俺は例外だろうとは思っているが、
APIは戻り値でエラーを知らせるから、惰性で例外処理を使わない。
ありがとうございました。
VisualStudio.net 2003で、 try { }catch(...) { >ここ };
236 :
デフォルトの名無しさん :2006/06/15(木) 20:28:17
おまいら、教えてください。 C#とかJavaなんかでは、例外をきちんと特定してキャッチするようにって言われてるよな。 まとめて一気にキャッチすんなと。 で、まとめてキャッチするのはエントリポイントでのみだ。 ここでは想定外の例外しかキャッチしないはずで、 ここでやるのはログを取ってアプリを落とす作業だ。 でも、普通、テスト漏れとかあって、たまに想定外の例外が発生することがあるよな。 漏れは今までどんなアプリでも落としちゃうようにしていたのだが、 特にずっと動かさなければならないサービスの場合は落とすなって言うヤツがいるんだ。 サービスの場合って落としちゃうのと落とさないのどっちがいいの?
ゲームなら多少表示が崩れても続けた方がいいし決済システムならさっさと閉じた方がいいだろう。 ケースバイケース。 例外が起こっても無理やり続けておかしな挙動になってもいいのか悪いのか。 これを問いただせ。 もしそれでも構わないというならログでも吐いとけ。
>>236 外部から再起動掛かることが保証されているなら落とすのが無難。
そうでなくて、常に動いていることが要求されるなら自分自身を再起動するのも一つの手。
その例外の内容が致命的でないなら言われる通り落とさなくてもいいかもしれない。
要は、ケースバイケース。
239 :
236 :2006/06/15(木) 20:45:20
参考になった。 ありがとう。
>>236 Webサービスなら、そのリクエストを無かった事にしてほっとく。
Webアプリなら、セッション殺してエラーページに遷移させてほっとく。
当然、リソースは例外が上までぶっ飛ぶ最中にfinallyでcloseされてるのが前提な。
普通のアプリは…、知らん。業務でプログラム組んだのはWeb系しかないぽ。
それは、Webサービスとかなら、異常時はクライアント側が再リクエストするとか、 そういう前提があってのことだよな。 というように、やっぱりケースバイケース。
Delphiはデフォルトで最上位のメインループが例外をトラップして握りつぶしてしまう恐ろしい言語だ。 一応ダイアログで表示はするけどそのまま続行してしまう。
まあ例外に対してプログラムを殺すか、殺さないかは処理系の自由だからな。 殺さない処理系の場合、例外の発生によって被害が進みまくったら最悪だが…。
244 :
デフォルトの名無しさん :2006/06/17(土) 15:38:52
>>242 ちょっと教えて欲しいのですがそれは適切な例外処理を書いてなかった場合の事ではないのですか?
端的に言えば例外処理をきちんと書いておけば問題ないのではないでしょうか?
そうです。
C#なんかエラーコードは例外でしか判断できない関数がほとんどだろ
247 :
デフォルトの名無しさん :2006/09/01(金) 02:37:26
そうだ、ExceptionとErrorってどういう風に扱ってる?(別物?似たような?)
例外とエラーの違いだろ
>>248 Exception(例外)を捕まえて何かしら対処した時点でError(間違い)。
そもそも視点が違うと思う。
Exceptionが引き起こされるのがエラー処理だし。
不適切なパラメータ渡されたときにエラー(間違い)チェックして例外飛ばしたとして、
それを受けてユーザーに再入力促すような処理はエラー処理だし、
そのままスルーしたらその段階でも想定してなかった例外処理と言える。
エラー処理のためにあるのが例外機構でしょ
例外 ⊆ エラー
Javaの定義
Exception:言語によって違う Error:言語によって違う だから一概にどうとは言えない なんて言う仕様原理主義の奴は氏ね
俺定義を押し付けたい奴も氏んでね。
/::::::::::::::::::::::::/. 二二二ニニ、 ハッ!! /:::::::::::::::::::::::::::/ ・/ :::ゝ、 l::::::::::::::::::::::::::::i : ! :::::::,! ──i^'i──┼''┴┬┬┬─--─'' i ヽ、 __! '゙i;:;:;;!/ / ヾ、  ̄`⌒゙ ` ,ノ ''ー-、,, ,;. 、,f |,、 !, ! f, ,y | ,ヘ /´ ,ノ ,!、 // _ r=、 ,/ ,;-'' `ヽ ゙; i^'i ;'、===ョ ゙iヽ\ .,,-=二二i__i 二二二ヽ _i ヽ、二! '゙i;:;:;;!/ /`" l::::::::::::::::::::::::::::i : !、  ̄ヾ、  ̄`⌒゙ ` ,ノ ヽ::::::::::::::::::::::::::゙、;ヽ ゙''ー-、,, ,;. 、,f \::::::::::::::::::::::::\ :゙''- ,,,__ _.. | '" i ゙| ` ──----−`'''ー---- ''".|,、 !, ! . f, ,y | /´ ,ノ ,!、 ,/ ,;-'' `ヽ ゙; i i ヽ ヽ、
catch (TaikoOpenException e) {
through e;
飲み込んじゃうのか。
C++相談室から誘導されてきた。…んだが、人いないな。 C++での話。例外仕様ってどうやって使ってる? 今までデストラクタやswapにthrow()と書いていたんだけど、 unexpectedするだけでさほど意味ないんじゃないかと思うようになって。
>>261 throw() は最適化に使われることがある。逆にパフォーマンスダウンする
コンパイラもあったが、もう昔の話と言えるかもしれない。
デストラクタに throw() を付けてないクラスのローカル変数を大量に含んだ関数を
コンパイルしたアセンブリ見て、あまりのアホコードに愕然としたことがある。
throw() 付けたら、だいたい思ったとおりのコードになってくれた。
gcc で std::exception を継承した例外クラスを作るとき、デストラクタを
明示的に宣言して throw() 付けないと警告でる。中身が空でも throw() を
指定するためだけに宣言が要る。
throw() 以外の例外仕様はうんこ。
>>261 例外投げるときは「責任が負えないが起こったとき」に限定してるから
どんなときでも「責任外」なら投げちゃってる俺ガイル
264 :
261 :2006/09/27(水) 22:30:53
>>262 参考になった、ありがとう。
脳内イメージでは "foo() throw() { body(); }" は
"foo() { try { body(); } catch (...) { std::unexpected(); } }" だったんで、
例外中立じゃないし余計なコードが入りそうに思ってた。
でも、デストラクタの場合は
「スタック巻き戻し中に例外が発生したら std::terminate() を呼ぶ」
って縛りがあるから、throw() が付いている方が最適化しやすいのかも。
わからんけど。
結局状況次第っぽいかな… いろいろ試してみるしかないか。
> throw() 以外の例外仕様はうんこ。
同意。欲張らず、コンパイル時の不送出保証をコードとして
記述できるようにだけしてくれれば、わりと満足なんだけどなー。
Windowsの人なんだなぁ
みつを
267 :
デフォルトの名無しさん :2006/10/01(日) 21:12:28
>>263 C++で「例外仕様」って言ったら特別な意味があるんだよ…
>>267 C++の例外はなぁ……
例外安全・例外中立とか、Exceptional C++呼んでもサパーリだった俺には使いこなせそうにない
>>268 そいつらがサパーリならC++に限らず、例外処理(エラー処理)のある
プログラムは書けないだろうね。
そうでもない。C++の例外安全はその言語仕様に根ざしたモノが多いから。 そんなこともわかんないようじゃ、C++も他のプログラムもちゃんとやってないんだね。
"例外安全" の検索結果 約 1,040 件中 1 - 10 件目 (0.14 秒) "例外中立" の検索結果 約 73 件中 1 - 10 件目 (0.16 秒) んー…んぅ・・・
>>270 例外安全性って、言語に依存せずに定義できるもんだと思うんだが、違うのか?
言葉の意味の幅としてはスレッドセーフと同じようなもんだろ。
「C++の例外安全」って何?
273 :
デフォルトの名無しさん :2006/10/01(日) 22:55:39
destructorのあるなしが、例外安全性に大きくかかわっていると思うのだが。
そんなこと書かれていないが?お前の感想だろ? まるでwikipediaに書いてあるかのように錯覚させるのはどうかと思うが。 ま、Cでも多少語ることが出来るが、本が書けるほどじゃない。 C++に比べるととてもシンプルだ。 Exceptional C++が理解出来ないとしても >例外処理(エラー処理)のある >プログラムは書けないだろうね。 はとんだアホレスだ
wikipedia の文言 "A piece of code is said to be exception-safe if run-time failures within the code will not produce ill-effects, such as memory leaks, garbled data or invalid output." に依るならばかなり普遍的な概念に読めるけれど
じゃあ試しにCの例外安全について語ってみ。 俺からだ。Cに例外が無いので例外安全も糞もねぇ。戻り値しっかり調べてろアホ。 はい、お前の番。
しかし日本語訳がスカスカと言うか、ないに等しいのは困ったもんだな。>Wikipediaのその項目
>280 いえですから私の理解では,言語仕様としての exception (例外)と wikipedia に書かれている exception safety (例外安全)を明確に区別しているだけです. 私の理解では,たとえばCにおいてある関数が例外安全であるといったとき,それは Cにおいてはその関数内でのエラー・例外的状況の通達手段が戻り値 (もしくはmutableな引数,グローバルな状態)しかないというだけで, 仮にそれらの通達手段で例外的な状況・エラーが通達されているとき,プログラムの状態 (非常に曖昧な言葉ですが,これはmutableな引数の状態からグローバルな変数の状態, ひいてはプログラムが実行されている環境の状態全てを指しえます) が無効 (invalid) な状態に陥ってないことと定めることができる,というものです. そして, wikipedia の文言もこう読めるのではないかという主張です.
で、Cでソレを達成するのは難しいか?難しくないだろうが。 C++での例外安全を理解出来なかったからといって 次のようなアホなことは到底言えない。 >例外処理(エラー処理)のある >プログラムは書けないだろうね。
284 :
282 :2006/10/02(月) 00:38:18
>283 あ,すいません.自分は277さんの >例外安全は C++ に限らず、プログラム一般の概念だ。 >言語は問わず、たとえ C でも例外安全性を語ることは出来る。 というレスに対してのみ賛同しているだけで, >>例外処理(エラー処理)のある >>プログラムは書けないだろうね。 という主張をしたいわけではないです.
コテもトリもつけないでオマイラ良く会話が成り立つな 俺には自演にしかみえん
例外安全自体は難しい概念じゃない。 C++でそれを達成するのが難しく理解が困難。わかる?
>>283 なんで C だと簡単になるの? C++ みたいに言語のサポート無いから余計に難しいだろ?
議論が噛み合ってないね。 282氏はWikipediaの内容をかいつまんでるだけ (あそこでは例外処理がエラー処理と同等の文脈で使われてることのみを確認している) で、他になんか主張を混ぜてるようには読めないけど。
>>289 ネタでもマジでもどっちでもいいから、C++では難しくて
Cでは難しくないと言う根拠を示してください。
だから、最初からC++と例外処理を切り離せばいいだけじゃん なんで皆なにも分かって無いのにウダウダ言ってるの? バカじゃない?
>>292 例外機構が言語に組み込まれてなければ例外が起こらないと、そういう認識なのね。
また「例外」の定義からやりなおしですか?
>>293 はぁ?何いってんの?
>C++では難しくてCでは難しくないと言う根拠を示してください。
根拠を示したのに、
>例外機構が言語に組み込まれてなければ例外が起こらないと、そういう認識なのね。
って解釈するって、どんだけアホなんですか。
ベタCで書いててもWin32APIが構造化例外投げてくる事はあるよ と余計にややこしい事を言ってみるテスト
try-catch よりも、スコープ外れた時に確実にデストラクタ呼びます、 とかの方が例外安全なコードの書きやすさに貢献してくれそう。
296 の続き。 try-catch のあるなしだと、 それが goto 文という名前か、 try-catch かの違いでしかないような。
>>294 例外機構の言語によるサポートがあったほうが
例外安全性の確保は簡単になると思っているので、
「Cでの例外安全達成が難しくない理由」と
>>292 とが
結びつかない。
俺、アホなのかな?
自動車で事故らない方法 一輪車で事故らない方法 どっちが簡単か? 一輪車はそもそも転ばないように乗り回すものだから、危険は承知。 とりあえず車道に出るやつはいねえだろうし。結論は簡単に出る。 自動車の事故は、ドライバーの状態・車体の状態・環境なんか複雑な要件が絡むので 議論は多岐にわたる。こいつは難しい。 通りすがりに訳の分からない例えをしてみる。
>>299 一輪車で遠くまで移動しなきゃならないこともある。
などとさらに通りすがりがツッコミを入れてみる。
まじめな話、「〜という(大規模な)処理をするプログラムを作れ。
言語はC限定。エラー対策は万全にしろ」と要求されることもある。
Cだから簡単ということはない(し、できないということもない)。
C++のように言語が例外機構を備えているなら、エラー処理の実装に
例外を適切に用いれば、より簡潔な記述で正しく実装できる。
ただし、当たり前だが使い方を間違えると意味がない。
ぶっちゃけCで書いてるときは例外安全性なんて考えてなかったんだろ?正直に言えよ。
その通りです ごめんなさい
>>301 漏れはいつでも「この関数longjmpで抜けていったりしねーだろうな。
リソースリークするぞ」と考えてはいたよ。
考えてただけで何もしなかったけど。
>>300 Cは何とか転ばないようにするしかない、という認識しかなかったもので。
実際そういうことを申し渡されると死ぬ思いな気がします。
エラーコードチェックしてばっかだとなんかifばっかで気が滅入ります('д`)
C言語では自前のメモリ管理機構使ってるよ。 これを発明(w)した当時は例外機構なんてイラネと思ったね。 f() { int h = enter(); // a alloc(h); g(); alloc(h); leave(h); // b } g() { int h = enter(); // c alloc(h); if (cond) return ; // error発生 leave(h); // d } main() { int h = enter(); __try { //スレッドの根っこに保険としてSEH f(); } __finally(cond) { leave(h); } } aやcでちゃんとleave(h);できなかったらfやmainでまとめて回収する。 longjmpしてもOK(どっかで必ず回収できる事が保障される)。 スレッドごとに必要な場合はTLS使う。 問題はいちいちenter/leave書くのが面倒な事。
Symbian OSも似たような自前の回収用リストを使ってるね。 Symbian OS は全 API/フレームワーク が C++ なんだけど、 言語処理系の例外処理を使わずに自前で例外とunwind 用の スタックを定義している。 これは ABI やライブラリの互換に縛られずにARMコンパイラとか gccとか使えるようにするためだと思うけど。
誰か、C#やJavaの例外安全性を語ってくれ。 C++と比較して、例外安全性を確保するのが容易なのか? それとも同程度に難しいのか?
安全確実な回収方法がtry..finallyとかしかなかったりするJAVAは ちょっとヒドいと思う。ファイナライザがあるとはいえ。 finallyのなかの解放部分をtryで囲むとかヒドス
C#のusingとIDisposableってのはどうなのよ?
C++ はスコープ抜けた後にデストラクタが必ず呼び出されるので クラス設計をきちんとやれる(もしくはきちんと設計したライブラリがある)なら 例外安全を意識する回数を減らせる。 ただし finally がないので、ちょっとした後始末をサクっと書けない。 きっちり書くことを強制するのは、むしろ利点だとの主張もある。 Java は 308 氏のに加えて、 チェックする例外とチェックしない例外(C#やC++はこっちだけ)がある。 チェックする例外の場合は try-catch 書かないとコンパイルされないので よほどのうっかりさんで無ければ例外処理を記述すするものの、記述は非常に煩雑。 素のAPIで記述するとDBアクセスやファイルアクセスは try-catch で二重三重に囲われて、本来の処理がノイズに紛れる。 ほぼ定型処理なので、フレームワークでうまく切り出して楽に記述できるように工夫する。 (チェックする例外を catch して、チェックしない例外でラップして throw する、なんてことをする。) C# はチェックしない例外だけ。 ただし using ステートメントを使うと、ブロック内を抜ける際に Dispose メソッドを呼ぶ。これはC++の「スコープ抜ける時にデストラクタ」みたいな感じ。 Java がかなり特殊で(チェックする例外なんてなくせよって声が小さくない)、 C# が柔軟、C++がガチガチって感じ。 Java は言語仕様・API の粒度が細かいんだと思う。 その代わりライブラリ・フレームワークは充実してる。 (よって1から書くと死ねる。)
>>311 純粋なCで書いたことってないんで、他にもっと詳しい人にお願いして。
goto 使うとある程度エレガントに記述できるけど
goto 排除原理主義者との戦いが待ってるとか。
finallyの代わりとしてgotoで後始末に飛ぶのは、条件判断が減ってエレガントだと思うんだがねぇ。 関数が短けりゃ、飛んでも読むのには苦にならないし。 まーこれは宗教の問題だから、賛成派も反対派も根拠なんてないんだが。
>>313 goto反対派って原理主義に陥っちゃってるから始末におえない、まさに例外でどっかに飛んでいってほしい
Cはsignalじゃねーの?
意味わからん
signal.hか。 使ったこと無いし、C標準のライブラリだったかも分かんないな。 0除算とかはキャッチできるらしいけど。
明示的な(意識して throw するような)例外となると setjmp longjmp が妥当か?
xxl
singal & raise は標準
singal じゃなくて signal だた
ファイルがオープンできなかったらraise()するのかよ。
FILE* fp = fopen("hoge","r"); if(!fp) { int i = 0/0; }
例外はなぜ必要? 例外の無いプログラムを書けばいいだけでは?
例外を送出する仕様のライブラリ・APIを無視できるならね。
>>325 なんでそのライブラリ/APIはそういう仕様なの?
と、誘導尋問してみる
>>324 OOBなイベントの発生を通知したいから。
>>324 その論理であらゆる機能を否定していろ。
どんな解を誘導しようとしたのかが分からん。
332 :
デフォルトの名無しさん :2006/10/03(火) 23:50:43
なぜかいまさらゆのはな始めた こういう軽快なテキストと掛け合いはもろツボだなぁ
333 :
332 :2006/10/03(火) 23:51:09
誤爆なので決して気にしないように
>332 何の話か分かってしまう俺はとりあえずthrowされた方がいいですかorz # いや、ゆのはなはやったことないんだが
C++やC#で育った人間だと、誤爆してもスルーだな。
J・さいろー氏が参加してるのか。
結局ANSI/ISO Cのみだと、どうやってやればいいわけ? setjmp? signal? error?
それ、後処理できないだろ! 後処理はどうやるんだ?
atexitに全部ぶちこんどけ
Cで例外を処理するライブラリー(例外機構の実装)とか そういう便利なのはないの? GCライブラリーはあるのに…
#define try do #define catch(e) while(0); if (e != 0 ) 失敗時に非0を返す戻り値のチェック 意味ねーけどな。
__try __except __finally って標準にならないもんかねえ。
>>342 Subversion の svn_error_t が、かなりがんばってる感じ。
>>345 Windowsの構造化例外の為だけに標準化するの?
まだC++のtry 〜 catchのほうが見込みがあると思う。
そういうわけではないが、たとえWindows発案でも、 Cで例外があるかないかは天地ほど違うと思う。
xxl でいいじゃん。
setjmp と longjmp でできるんじゃないか? try { A } catch (e) { B } finally { C } は、 switch (setjmp(&jmpbuf_table[++sp])) { case 0: A; break; default: B; } C; --sp; throw (e) は longjmp(&jmpbuf_table[sp]); てな感じで。
goto の方が読みやすくない?
goto使うやつは低脳
↑低脳の典型例
書籍 Exceptional C++ Style―40のクイズ形式によるプログラム問題と解法=スタイル編 ハーブ サッター (著), Herb Sutter (原著), 浜田 真理 (翻訳), 浜田 光之 ASIN: 4894714663 出版社: ピアソン・エデュケーション
買ってきた。今読んでるところ。
なんで More Exceptional C++ より先に Exceptional C++ Style が和訳されたんだろう?
std::exception ってワイド文字版無いんだな・・・ 仕方ないから、UTF-8に変換して喰わせているんだが、もう少しマトモな方法ないかな?
>>358 virtual template が使えないしな
規格ではNTBSを返せって話になってるから
NTMBSとかNTWCSとはまた違うんだとは思う
>>358 map<string,wstring> へのキーを入れるとか。
でも、ファイル名とかの文脈情報を載せる方法を考えないといかんね。
>>358 いっそのことstd::exceptionのwchar_t版を作ってしまえ。
このまわりはホント、標準が糞なんだよなぁ。
文字コードなんて些細な問題だよ
本来些細であるべきなのに ロクに標準化されてないから 不毛なんだよね。
差し当たりは全部英語で書いておくのが無難かね
wchar_tなんて何バイトか分からん型を標準なんかにせずに、 「C、C++はUTF8が標準!!!!」って言っちゃえば良かったのに。 大体、 _t なんてゴミが付いてるのが組み込み型なんて気持ち悪すぎ。
あー、そうすると「char型は8ビットとは限らない」とか言い出す原理主義者が 沸いてくるのか・・・ 面倒だな・・・
文字コードとか気にする場合は文字列に対応するハッシュ値や
ユニーク値を投げるのが普通じゃないのか。
>>360 もそういう事かな。
例えばcharのサイズを固定せず柔軟であるからこそ 今でもCは受け入れられているのでないか? wchar_tやcharを云々言うのは言語Cの話とは関係ないだろう。
>>369 それいっちゃうと、文字コードの話とかcharとかは
例外処理に関係ないってか、スレ違いっつーか。
371 :
デフォルトの名無しさん :2006/12/01(金) 22:07:05
ここまで読んだ
最近急に例外に興味が沸いてきて本も探してた所なので
名前が挙がってた Exceptional C++ も読むことにする
あと、
>>202 の言わんとしてるところが、判るようで微妙に判らない
プログラムの実行に支障をきたさないようなエラーって何かおかしい気がするんだけど
日本語のアヤでどこかひっかかってるんだろうか
>>371 横レスだけど、それって(この例だと)
ファイルが無いときに困りはじめるところで例外を出せってことじゃないの?
一般的にファイルを扱うところ(言われたことをするだけ=下請け)と
各プログラムでそれを呼び出すところ(元請け)の違いではないかと
あさっての方向だったらゴメン
まぁ例外とエラーは違うっつー話でFAC
>>371 (一部すっとばすなどして)処理を続行可能な軽微なエラーのことだと思う。
string.find()で-1が返るのもエラーと言えなくはないな
匙を投げる代わりに例外を投げてるんだろ
>377 Javaのcharも、C#(CLR)のcharもUTF-8じゃないんだが。
379 :
デフォルトの名無しさん :2006/12/04(月) 14:57:59
とりあえずありえないような例外をCatchはしないようにしている くらいかなぁ・・・ 後一元管理でスタックトレースをログ保存してるくらいか・・・
チェック例外と非チェック例外が共存するのってどうなんかな。 最近は専らJavaで書いてるけど、この共存状態は 便利さよりも危うさ・不明快さが勝るように感じる。 全部チェックもしくは全部非チェックじゃダメだったんだろうか。 ありえない状態はError投げれば良いし。 100歩譲ってRuntimeExceptionはThrowableから直接派生させるべきだったのでは。
>>380 全部非チェックにすりゃよかったのに、って意見は多いよな。 後出しだけど。
全部チェックにすると、OutOfMemoryとか常に出る可能性があるからなんかだめぽ。
OutOfMemoryErrorが追加されたんじゃなかったっけ
Error は別にあるのに Exception のサブクラスで RuntimeException を作ると言うクラス階層が 生理的に不自然に感じる。
VC#のWeb参照でWSDLからクラスを自動生成すると FAULTを思いっきりスルーしてくれるから困る。
385 :
デフォルトの名無しさん :2006/12/19(火) 06:47:46
C++でアプリを正常終了する時に例外を投げるのって邪道?
ずっと稼動してる様なアプリだと、シグナルがきたら終わるとかよくやるけど そこで例外投げるってのはどうかと思う。 >例外は、それを取り巻くコードの >構造と意味を、根底から覆します。例外は、プログラムの実行時 >セマンティックを一時的に繋ぎ変え、通常実行しているコードを迂回し、 >こういう状況でなければ決して実行されないコードを動作させます。
間違いってことはないが、明らかに設計が普通ではない
例外って飛んできたらexitするしかないような処理でしょ。
暗号化したコードを復元するためのシグナルに、例外を使ったことがある。 反省はしない。
どこから飛んできたのか探すのが大変だから、正常系の処理に例外は使うなってこった。遅いし。 明らかに復帰不可能な例外なら投げてもいいけど。
>>389 それが決まってるなら exit() すればいいわけで、例外投げる意味が無い。
>>392 exit()するとオブジェクトの始末がされないのでは?
exitするしかないような事態で、正常に後始末できるの?
>>392 ローカルオブジェクトのデストラクタは呼び出されないね。
意味が無いわけじゃないな。
だからといって例外の使い道がそんな場合に限定されるわけじゃないよ。
catch した人が処理を選択できるのが例外の重要な意義なんだから。
>>394 なんでできないと思うの?
exitするしかないような事態って、ディスクとかネットワークトラブルとか思い浮かべてたんだけど そんな状態で正常に後始末できるのかなと
コード上のリソース(ヒープとかファイルハンドルとか)の後始末じゃね? C++ だと例外安全かどうか気をつかうことになりそうだけどサ
C++に正解などない。 書きたいように書けばいいじゃないか。
しかし定石はあると言えないか?
Hoge::Hoge():pint( new int ){}; これは間違いだと言いたい。
Hoge::Hoge():pint( new int ){}; には別に悪いことはないんじゃない。 ただ、コンストラクタ/デストラクタで例外出すのはやめて欲しいがな
>>402 コンストラクタは別にいいだろ。他にどうやって失敗を通知するんだ?
コンストラト処理中に例外発生した半端なオブジェクトに対して デストラクタは呼ばれない
該当半端オブジェクトの、例外発生前までのうまくいっている部位の後始末をどうするかが面倒
ってことで、問題を簡単化するのに
>>402 な希望だと思う
それぞれのメンバが適切に RAII のルールを守っていれば話はもっと単純にできる。 それをせずに「コンストラクタから例外禁止」なんて新しいルールを作るのは良くない。
>例外発生前までのうまくいっている部位の後始末をどうするかが面倒 後始末が必要なものはクラスで包めばいいじゃん。
結局RAIIに徹しろっていう普通の関数の例外安全性の議論と大差ないよね>コンストラクタ RAIIが面倒な場合は初期化子リストにtry-catch仕掛けることもできるし 一般にコンストラクタは強い例外安全性を達成するべきという主張なら十分納得できるんだけれど
class A { Hoge *hoge; //どっちともコンストラクタで例外を出す可能性があるクラス Hage *hage; A() try:hoge( new Hoge ), hage( new Hage ) { } catch( ... ) { 初期化子にtry-catch掛けられるったって、こういう状況は非常に面倒くさい。 new Hageで例外でたらどーすんだ? }
> 後始末が必要なものはクラスで包めばいいじゃん。
> 後始末が必要なものはクラスで包めばいいじゃん。
初期化子を使わずにコントロールしろということなのかな?
>>408 の例だと
A()
{
try { hoge = new Hoge; } catch(...) { throw ; }
try { hage = new Hage; } catch(...) { delete hoge; throw ; }
};
スマートポインタ使えばいいのに
class A { std::auto_ptr<Hoge> hoge; std::auto_ptr<Hage> hage; A() : hoge(new Hoge), hage(new Hage) {} }; これでどちらで例外が投げられても大丈夫。
>>412 AのA のデストラクタが呼ばれないのは分かるけど、A::hoge と A::hage のデストラクタは呼ばれるの?
スマートポインタって自身のデストラクタ呼ばれないと機能しないような気がするのだが
>>413 コンストラクタが完了したものはデストラクタが呼ばれる。
new Hageで例外が出ても、hogeは構築済みだからデストラクタが呼ばれる。
415 :
413 :2006/12/22(金) 19:57:38
>>414 てんきゅう。 自分もコード動かして確認した…
例外周りのメンバの取り扱いはややこしいねぇ
実際投げてる例外はおいといてくれw
class Hoge {
public:
Hoge() { std::cout << "Construct Hoge" << std::endl; }
~Hoge() { std::cout << "Destruct Hoge" << std::endl; }
};
class Hage {
public:
Hage() { int e=1; throw e; }
};
class A {
std::auto_ptr<Hoge> hoge;
std::auto_ptr<Hage> hage;
public:
A() : hoge(new Hoge), hage(new Hage) {}
};
int main() { try { A a; } catch (...) { } return 0; }
構築に成功したオブジェクトは必ず解体に成功する 構築に失敗したオブジェクトは解体する必要がない 何か気をつける余地が0になるのがRAIIのありがたいところ
new Hageで確保されたメモリは開放されんの?>auto_ptr
>>418 んーごめん。まったくわからん(´д`;
>>419 new Hage の動作を分解すると、
void* storage = operator new (sizeof(Hage));
try { new (storage) Hage; }
catch (...) { operator delete (storage); throw; }
こんな感じになってるわけよ。
ぉぉ。そうなんですか。 あざーす
だれもいない
じゃあ話題振るか。 システム内部は全てワイド文字で処理してるプログラムの例外って みんなどうしてる? std::exceptionのwhat()ってconst char*しか扱えないじゃない? そうするとシステム内部のワイド文字列を例外に載せようとした時、 2つの解決方法があると思うんだ。 1つはその文字列をマルチバイト文字列にコンバートして std::exception(の派生クラス)で投げる。 もう1つはワイド文字列を運べるwexceptionクラスを自作する。 1だと投げる時WCS>MBS、捕まえて表示するときMBS>WCSと 無駄な処理が発生する場合がある。 2だとSTLとかが投げる例外と自分のシステムが投げる例外が 同じ処理をする場合でも、いちいちcatch節を2つ書かなきゃならない。 まあ例外は全てMBSで扱って表示もMBSでしかしないってのもアリだけど
typedef struct what { int id, wchar *hoge; } what; exception((char *)w);
what()はデバッグ時にトレース出力くらいしか使ってないや。
>>423 一番堅いけれど面倒なやり方として,
エラーの識別子のみを std::exception に載せる std::string の情報とする扱い方.
エラーを人間に読めるようなメッセージに変換する必要があるならば,
メッセージカタログなりを使ってエラーの識別子とエラーメッセージとの対応を取る.
この場合,表示するメッセージを MBS とするか WCS とするかのポリシーは
メッセージカタログの責任範疇となって, std::exception と独立となるのが利点.
>>426 std::exceptionにstd::stringに埋めちゃうのは、std::stringのコピーコンストラクタ
が例外を発射する可能性があるから、やばいのでは。
例外処理の運用については、
>>423 的な悩みも含めて Boost の
http://www.boost.org/more/error_handling.html がとてもよくまとまっていると思う。
(翻訳版はバージョンが古いのか、内容が違う)
あとはexception safty(例外安全性(?))やexception neutral (例外中立性(?))
なクラスの設計、実装について、Exceptional C++, More Exceptional C++,
Exceptional C++ Style の該当項目に目を通せばOK。
428 :
426 :2007/01/15(月) 22:01:37
429 :
423 :2007/01/15(月) 22:06:59
>>426 Win32APIのGetLastError()とFormatMessage()みたいなことかな。
できれば問題が起きた原因たるオブジェクト(の内容)を
例外ハンドリングしてるところまで持ってって表示してあげたいんだけど、
その方法じゃ無理だね。困った。
>>427 つまり↑みたいな野望は無駄な足掻きってことかな…。
staticなエラーメッセージ保存領域作っておいて
そこにコピーしてから例外飛ばすとか?
てか、もしかしたら例外で処理すべき問題じゃないのかもしれない…
>>423 規格にある std::exception::what() についての記述には、
wstring に変換して表示するのに適した NTMBS でもよい、とある。
規格に沿うようにしたいのなら、このアプローチがいいってことね。
>>429 >Win32APIのGetLastError()とFormatMessage()みたいなことかな。
みたいなことですね。
>できれば問題が起きた原因たるオブジェクト(の内容)を
>例外ハンドリングしてるところまで持ってって表示してあげたいんだけど、
エラーの文脈情報を付加したいという話ですよね。そのエラーに対応する
std::exceptionの派生クラスのメンバ変数に持たせれば可能なのでは。
>
>>427 >つまり↑みたいな野望は無駄な足掻きってことかな…。
いや、427ではstd::exceptionにstd::stringを「埋める」とやばいという話を
しましたけど、ポインタで(例えばstd::auto_ptr<std::string>)で持たせれば
問題はありません。string以外の文脈情報についても同様です。
今度はnewが例外を投げるのでは、という心配が。
>>432 例外クラスの設計で注意しなきゃいけないのは、スタックの巻き戻しを
している最中に呼ばれる例外クラスのコピーコンストラクタが例外を
発射しないことです。
この状況になると通常、terminate()直行で、どこのエラーで落ちたのか
もわからない結果になります。
それ以外の状況なら例外処理中に例外が発生しても対処は可能でしょう。