1 名前:デフォルトの名無しさん (ワッチョイ efda-9b8G) mailto:sage [2023/10/31(火) 07:37:38.52 ID:+ZyYyqMO0.net] !extend:checked:vvvvv:1000:512 !extend:checked:vvvvv:1000:512 ↑同じ内容を3行貼り付けること 次スレは>>980 が立てること 無理なら細かく安価指定 ※前スレ C++相談室 part164 https://mevius.5ch.net/test/read.cgi/tech/1683600652/ VIPQ2_EXTDAT: checked:vvvvv:1000:512:: EXT was configured
93 名前:デフォルトの名無しさん [2023/12/24(日) 19:45:29.51 ID:Y8qSN/i/0.net] ストリーム用の演算子なんか作らずに オブジェクトの文字列表現を返す関数を用意したほうが汎用性高くない?
94 名前:デフォルトの名無しさん mailto:sage [2023/12/24(日) 19:50:06.00 ID:foDTiHm90.net] Foo obj; std::string s = obj.str(10); // 10億ギガ文字 cout << s; 出力を完遂できるんかこれ……
95 名前:はちみつ餃子 mailto:sage [2023/12/24(日) 20:00:55.29 ID:SfA3xmSz0.net] C++20 からは std::formatter を特殊化して書式指定を解釈するコードを入れておけば std::format で独自の型を表示しようとしたときにその特殊化が使われる仕組みになってる。
96 名前:デフォルトの名無しさん [2023/12/24(日) 21:41:50.00 ID:Y8qSN/i/0.net] オブジェクトの文字列表現が10億ギガ文字もあるの!? FooWrpオブジェクトをうっかりログに出力しちゃったら大変だね!!
97 名前:デフォルトの名無しさん (ワッチョイ cf63-nyJS) mailto:sage [2023/12/29(金) 19:34:46.18 ID:MPSeCS+O0.net] 実験せずに質問するますが、 int a, b; cin >> &x >> &y; に対し、 Q1. 「100 a」を入力したら例外もタイムアウト待ちも発生せず、cin.fail()がtrueになるだけ? Q2. 「100」とだけ入力してそのまんま(リダイレクト元のファイルハンドルか何かが タイムアウトもエラーもクローズもしなければ)ならそれっきり返ってこない?
98 名前:デフォルトの名無しさん (ワッチョイ cf63-nyJS) mailto:sage [2023/12/29(金) 19:40:39.84 ID:MPSeCS+O0.net] EOFが抜けてたorz Q2のケースにおいて「100 [EOF]」なら(多分)cin.fail()でとりあえずすぐ返ってくるのかそうか、
99 名前:はちみつ餃子 mailto:sage [2023/12/29(金) 21:37:06.10 ID:0cvltfsQ0.net] >>97 実にしょうもない確認なんだけど、 言いたいことは int x, y; cin >> x >> y; でよいんだよね?
100 名前:デフォルトの名無しさん (ワッチョイ de63-J7+h) mailto:sage [2023/12/30(土) 05:42:41.89 ID:3ksfrMrT0.net] >>99 >int x, y; >cin >> x >> y; おk スマンカッタorz エラーとEOFのどちらかを検知したかったら!cin.good()が正しいっぽい? https://blog.emattsan.org/entry/20110819/1313743195 ここまでは分かった気がするが、 ストリーム入力演算子std::istream& operator>>(std::istream& os, Foo& obj)の中で入力に失敗した場合 どうやってエラーを呼び出し元に通知したらええんじゃ……
101 名前:デフォルトの名無しさん mailto:sage [2023/12/30(土) 05:50:37.02 ID:3ksfrMrT0.net] クラスFooの入力ストリーム演算子の中で整数を2個読むとして、 std::istream& operator>>(std::istream& os, Foo& obj) { int x, y; os >> x >> y; if (!os.goot()) { return os; // エラー発生時は単純にreturn os; でおk? } obj.m_x = x; obj.m_y = y; return os; }
102 名前:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 43c3-KM86) mailto:sage [2023/12/30(土) 08:47:16.28 ID:XV37Te4m0.net] >>100 ストリームのフラグを立てるメンバ関数は setstate だけど >>101 の状況ならフラグはもう立ってるから戻るだけで問題ないよ。
103 名前:デフォルトの名無しさん mailto:sage [2023/12/30(土) 13:48:41.88 ID:3ksfrMrT0.net] わかりた ていうかエラー判定(eofbit以外のビットのセットを判定)なら!os.good()や!os.goot()ではなくて os.failed()か!osですたね……orz これらに関して追加の質問が出たら初心者スレに書くわサーセン;;;
104 名前:デフォルトの名無しさん mailto:sage [2023/12/31(日) 20:09:05.68 ID:tpduSr4A0.net] class A{ char buf_[size]; } このbuf_に任意のオブジェクトをplacement newして使用するのだけど このオブジェクトをコピーしたりムーブする場合、単純にコピー元のbuf_からコピー先のbuf_にmemcopyしてしまって大丈夫ですか?
105 名前:デフォルトの名無しさん mailto:sage [2023/12/31(日) 20:44:02.18 ID:bvEcnWMM0.net] 全く大丈夫じゃない 初心者スレからどうぞ
106 名前:デフォルトの名無しさん mailto:sage [2023/12/31(日) 20:54:11.90 ID:NNsdlVTY0.net] 構造体から派生させれば出来るよ
107 名前:デフォルトの名無しさん mailto:sage [2023/12/31(日) 21:04:16.47 ID:bvEcnWMM0.net] せめてPODと言おう 初心者スレからどうぞ
108 名前:はちみつ餃子 mailto:sage [2024/01/01(月) 00:18:02.48 ID:6hyMwo3D0.net] POD は削除された。 trivially copyable の要件を満たすならその型は memcpy でコピーしてもよい。 std::is_trivially_copyable で判定できるのでどこかに制約を入れておけば安心かもね。
109 名前:デフォルトの名無しさん mailto:sage [2024/01/01(月) 00:36:03.09 ID:an53Mx2V0.net] 削除されたんですか?(バージョンいくつで?) c++20 で非推奨になった、てのはすぐ調べられたんだけどその先が分からんです
110 名前:はちみつ餃子 mailto:sage [2024/01/01(月) 00:46:07.42 ID:6hyMwo3D0.net] >>109 規格の文面としては C++20 で POD はもう削除されていて POD の概念を使わない形で再編されてる。 std::is_pod はまだある (非推奨) からこれが POD の定義だという意味ではまだあるとも言えるけど。
111 名前:デフォルトの名無しさん mailto:sage [2024/01/01(月) 00:46:34.65 ID:l/ylj5kb0.net] アライメント忘れてるぞ
112 名前:デフォルトの名無しさん (ワッチョイ e1f0-JZT3) mailto:sage [2024/01/01(月) 03:01:35.02 ID:5pNbZa2B0.net] >>104 まず自分でコード書いてみ よろしくないところは指摘してやるから
113 名前:デフォルトの名無しさん (ワッチョイ 8101-KEYj) mailto:sage [2024/01/01(月) 03:14:22.37 ID:8zoq4UeO0.net] オワコン名称出してマウント。プークスクス
114 名前:はちみつ餃子 mailto:sage [2024/01/01(月) 03:40:47.98 ID:hmX3WjmM0.net] POD が削除されたかどうかは重要ではなくて、 POD より弱い制約 (trivially copyable) で memcpy が許されるというのが主旨。 その点は C++11 からそうなってる。
115 名前:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 823e-OTTg) mailto:sage [2024/01/01(月) 04:06:49.46 ID:hmX3WjmM0.net] 「構造体」ってのも C++ 用語的にはイケてないと思うよ。
116 名前:デフォルトの名無しさん [2024/01/01(月) 04:55:26.71 ID:e5pnn2Xx0.net] アライメントは基本型のどれかと同じアライメント制約に合わせれば良いいということなら 使おうとしているうちで最も厳しいアライメント制約に一致する基本型を含むunionで解決するというのがC言語における伝統的な手法という印象、 C++でunionにしたら(それが可能なメンバのみなら) memcpyは安全とかにはならない?
117 名前:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 823e-OTTg) mailto:sage [2024/01/01(月) 05:30:52.12 ID:hmX3WjmM0.net] >>116 コンストラクタや代入演算子がトリビアルであることなどの制約を守れば共用体も trivially copyable になりうる。 (C++ の共用体はコンストラクタやメンバ関数を定義できるがそこらが制限されることになる。)
118 名前:デフォルトの名無しさん [2024/01/01(月) 14:24:55.17 ID:kge3DGj60.net] char* と long* のコピーは?
119 名前:はちみつ餃子 mailto:sage [2024/01/01(月) 15:31:30.97 ID:hmX3WjmM0.net] ポインタも含めてスカラ型は Trivially copyable https://timsong-cpp.github.io/cppwp/n4861/basic.types#9
120 名前:デフォルトの名無しさん mailto:sage [2024/01/03(水) 23:34:38.84 ID:w4EAqTeZ0.net] >>112 とりあえず書いてみたけどどうですかね? template<std::size_t buf_size> struct A { private: struct base_ { virtual ~base_() {}; }; template <typename F> struct derived_ : base_ { F f_; derived_(F f) : f_{ std::move(f) } {} }; base_* p_; alignas(alignof(std::max_align_t)) uint8_t buf[buf_size]={0}; public: A() :p_(nullptr) {}; template <typename F> void assign(F f) { if (p_ == nullptr) { p_ = ::new (buf) derived_<F>{std::move(f)}; } } //コピーコンストラクタ A(A& src) { p_ = ::new (buf) decltype(src.*p_); //ここが怪しい }; };
121 名前:デフォルトの名無しさん mailto:sage [2024/01/04(木) 00:44:07.87 ID:/FDyuY0i0.net] decltype(src.*p_)ってbase_なのでダメだろう
122 名前:デフォルトの名無しさん mailto:sage [2024/01/04(木) 00:58:18.81 ID:ECF9R1Fj0.net] ていうか、decltypeで型指定してるだけだからコピーもなにもされてないぞソレ
123 名前:デフォルトの名無しさん mailto:sage [2024/01/04(木) 02:28:40.49 ID:oZapr/U70.net] std::anyのコードでも読んだほうが早い
124 名前:デフォルトの名無しさん mailto:sage [2024/01/04(木) 09:11:56.12 ID:/FDyuY0i0.net] A::base_に以下を足してA::derived_で実装し Aのコピーコンストラクタから呼べば? virtual base_ *clone (void *p) = 0;
125 名前:デフォルトの名無しさん [2024/01/04(木) 13:26:37.40 ID:1KQpMTCj0.net] void*って、ポインターの先のサイズ未知だよなぁ
126 名前:デフォルトの名無しさん mailto:sage [2024/01/04(木) 17:16:40.43 ID:ACseOt7T0.net] derived_かそのメンバf_の型を知るにはRTTIしかないのですかね? >>121 decltypeだと派生先の型はわからないのか >>122 実体のコピーの処理が抜けてました…
127 名前:デフォルトの名無しさん mailto:sage [2024/01/04(木) 21:53:05.60 ID:ACseOt7T0.net] >>124 こんな感じです? struct base_ { virtual base_* clone (void *p) = 0; virtual ~base_() {}; }; template <typename F> struct derived_ : base_ { F f_; derived_(F f) : f_{ std::move(f) } {} base_* clone (void *p_buf){ return new(reinterpret_cast<derived_<F>*>(p_buf))(f_); } }; A(A& src) { p_ = src.clone((void*)buf); };
128 名前:デフォルトの名無しさん mailto:sage [2024/01/04(木) 22:19:16.70 ID:ECF9R1Fj0.net] derived_(F f) ←この時点でムダなコピーが1度発生していることには気付いてる?
129 名前:デフォルトの名無しさん mailto:sage [2024/01/04(木) 22:21:15.81 ID:/FDyuY0i0.net] >>127 書き込む前にコンパイルしなよ
130 名前:デフォルトの名無しさん mailto:sage [2024/01/04(木) 22:41:26.61 ID:Dv09vJ7A0.net] バッファの中にオブジェクトを作れたら、それで何をしたいのかが気になる
131 名前:デフォルトの名無しさん mailto:sage [2024/01/04(木) 23:21:36.86 ID:oZapr/U70.net] >>127 cloneの中ってplacement newでcopy constructorを呼ぼうとしてるんだよな? いちおうあってるけどundefined behaviorまみれ
132 名前:はちみつ餃子 mailto:sage [2024/01/04(木) 23:35:27.70 ID:td6kYpbC0.net] たぶんやりたいことは std::allocator_traits::construct なのかな
133 名前:デフォルトの名無しさん (ワッチョイ 7f7c-JApz) [2024/01/11(木) 04:45:44.72 ID:wlSOhq+Y0.net] 例外って全部mainで捕捉すべきかな? 調べてみたら例外が捕捉されずにプログラムが終了する場合スタックアンワインドが起こるかは実装定義みたいなんだけど、それじゃグローバルなオブジェクトのデストラクタが呼ばれないんじゃないかって思って試してみたのよ。 https://ideone.com/wSLZfL やっぱりデストラクタは呼ばれなかったからリソースリークが起こりうるんじゃないかと思うんだけど、例外に対してはどういう態度でいるべきかな? A. リソースリークはまずい。だから例外は全部捕捉するべき。 B. 例外はロジック上捕捉する必要があるものだけ捕捉して、それ以外はほっといていい。 C. 例外が捕捉されなければstd::abortが呼ばれるので、コアダンプなりで色々調べることもできる。だからmainで例外を全部握りつぶすようなことはすべきではない。 D. 時と場合による。 例外時の挙動とか仕様とか調べてるうちに頭ぐるぐるしてわけわかんなくなってきた
134 名前:デフォルトの名無しさん [2024/01/11(木) 08:40:16.50 ID:8oRrkiTZ0.net] そもそもプログラムが終了してリソースリークするのかな? メモリー、ファイルハンドル、ソケット、ミューテックスなどのリソースはOSが責任持って解放するよね どのようなリソースがリークしますか?
135 名前:デフォルトの名無しさん mailto:sage [2024/01/11(木) 08:45:02.51 ID:ETJgFBFV0.net] すべてじゃね?
136 名前:デフォルトの名無しさん mailto:sage [2024/01/11(木) 08:46:53.81 ID:ETJgFBFV0.net] >>133 すべてじゃね? それらの選択肢は別に排他的な選択肢じゃないかと
137 名前:デフォルトの名無しさん (ワッチョイ 7f3a-NF1f) [2024/01/11(木) 09:02:22.25 ID:dA95iQ6m0.net] OS管理なリソースはアプリの終了なんか知らないってのもあるからなぁ 得にドライバ関連とかな
138 名前:デフォルトの名無しさん mailto:sage [2024/01/11(木) 15:30:41.76 ID:hAXa3uBd0.net] >>136 あれ、少なくともAとCは排他的だと思うんだけど 全部の選択肢を選ぶとすると具体的にはどうなるのかな
139 名前:デフォルトの名無しさん mailto:sage [2024/01/11(木) 20:09:25.46 ID:AWAYnmwT0.net] 今どきのOS使ってたらOSリソースはリークしない まぁプロセスがゾンビになるのはよくあるが
140 名前:デフォルトの名無しさん mailto:sage [2024/01/11(木) 20:09:51.72 ID:AWAYnmwT0.net] >>137 しったかすんな
141 名前:デフォルトの名無しさん mailto:sage [2024/01/11(木) 20:12:29.21 ID:h5T3Zf1WM.net] そもそもアプリ的にデータの不整合とか出るから論外だろう ファイルやなんかの外部データ使わないなら関係ないだろうけど
142 名前:デフォルトの名無しさん mailto:sage [2024/01/11(木) 20:12:30.15 ID:AWAYnmwT0.net] よくあるのは異常終了時にファイルをフラッシュしておきたいとかだろ 汎用的にこれを実現するのは結構むずい
143 名前:デフォルトの名無しさん mailto:sage [2024/01/11(木) 20:14:10.04 ID:AWAYnmwT0.net] あとコアダンプの観点では例外飛ばさずに即死したほうがいい
144 名前:デフォルトの名無しさん mailto:sage [2024/01/11(木) 21:36:53.22 ID:40hQdtQK0.net] エラーだからって一時ファイル山盛り残して放置しないでください
145 名前:デフォルトの名無しさん mailto:sage [2024/01/11(木) 22:44:37.94 ID:wlSOhq+Y0.net] 質問した者だけど 確かに近代的なOSであればリソースの始末はよしなにやってくれるだろうし、「絶対にデストラクタが呼ばれなきゃ困る」って状況でもなければいちいちすべての例外を捕捉する必要はないのかな(毎回ボイラープレートコードみたいに書くのもやだし)
146 名前:デフォルトの名無しさん mailto:sage [2024/01/12(金) 01:18:38.26 ID:P05ikaaEd.net] 例外処理って、メモリ破壊やファイルシステム破壊みたいな絶望的な状況を想定しなきゃいけないんだよ。 ファイルに何か書き込んだら他のファイルを壊しちゃうかもしれない、みたいな。 だからファイル関連の操作をしていいのは、ファイルシステム周りの無事を確信できるときだけ。 データを上書き保存とかしていいのは、データとファイルシステム両方の無事を確信できるときだけ。 何も確信できないときは、何もせずに墜ちなきゃいけない。 ってことで例外機構はデフォルトで何もせずに異常終了するようになってるんだよ。
147 名前:はちみつ餃子 mailto:sage [2024/01/12(金) 02:09:19.72 ID:Z8/dVhwe0.net] 理想的には全ての例外はキャッチされるべき。 ただ、現実は理想的ではない。 キャッチするのは対処するためなので想定漏れで思ってもなかったような例外が上がってきた (対処が出来てない) ならそれはバグなんだから検証して修正する必要があるわけだし、検証しやすい形で止まったほうがいい。 C++ ではスタックの巻き戻しの途中で例外を送出したときの挙動は未定義なので通例ではデストラクタから例外を投げないように設計される。 つまりデストラクタでの後始末に失敗したらもうそれを (例外機構の仕組みでは) フォローできない。 想定されてない例外が上がってるときに後始末がちゃんとできずにわけのわからない動作を引き起こしたら検証にも支障がある。
148 名前:デフォルトの名無しさん (ワッチョイ 7f7c-acFs) mailto:sage [2024/01/12(金) 09:48:31.22 ID:1nCpSyqU0.net] じゃあ「投げられうるすべての例外に適切な対処ができるのが理想的だが、対処しきれない例外は投げられっぱなしにする(そしてプログラムを即座に異常終了させる)方が、思考停止でとりあえず捕捉しておくよりはまだマシ」ってことになるのかな みんなありがとう
149 名前:デフォルトの名無しさん (ワントンキン MMdf-7Pe6) mailto:sage [2024/01/12(金) 09:51:15.81 ID:Vmsz+UsIM.net] いやいや、ちゃんとデバッグしろよ こんなやつとは絶対一緒に仕事したくない
150 名前:デフォルトの名無しさん (ワッチョイ 5f4e-1VUN) [2024/01/12(金) 09:58:11.40 ID:yLdIK4jH0.net] ライブラリ書くときはライブラリで対処できない例外は握り潰さずに上位で伝搬させろ!と言われてるよね アプリも同じだと思う 明確に対処すべきことがあるなら例外をキャッチすればいいし ないならそのままプロセス落としてOSに任せればいいんでない?
151 名前:デフォルトの名無しさん mailto:sage [2024/01/12(金) 10:01:16.79 ID:1nCpSyqU0.net] 投げられっぱなしにするって言い方が不適切だったかな、別に例外のせいでプログラムが実際に異常終了するのを見ても知らんぷりするって意味じゃないよ 実際にプログラムが異常終了したんだったらその都度原因は突き止めて修正するし、そもそもすべての例外に網羅的に対処するのが現実的なときは最初からそうするよ
152 名前:デフォルトの名無しさん mailto:sage [2024/01/12(金) 10:06:03.47 ID:Umd8uX9b0.net] try {} catch {}
153 名前:はちみつ餃子 mailto:sage [2024/01/12(金) 17:12:14.63 ID:Z8/dVhwe0.net] 想定される状況には対処しているならどこで想定漏れがあるかはやってみないとわからない。 経験を蓄積し続けるしかしょうがないんだよな。 蓄積がテストケースの形などになっているとより良いと思う。
154 名前:デフォルトの名無しさん mailto:sage [2024/01/12(金) 17:26:50.90 ID:059LeD4FM.net] 自分の知らないライブラリの奥底からいつ投げられるかわからない例外なんて対処しようがない かつスタックアンワインドしたらデバッグの手がかり消えるだけ
155 名前:デフォルトの名無しさん (ブーイモ MM9f-2j6O) mailto:sage [2024/01/12(金) 17:44:35.30 ID:bUlwQWI8M.net] setjump()/longjump()
156 名前:デフォルトの名無しさん mailto:sage [2024/01/13(土) 13:54:58.62 ID:rNqWj2dY0.net] やっぱC++の例外は悪…… 構造化例外ならwindbgでコアダンプを開いて!analyze -vで発生源を調べられる(仕組みは知らん がC++の例外は例外オブジェクトが持ち出した情報が全て…… という印象……
157 名前:デフォルトの名無しさん mailto:sage [2024/01/13(土) 14:10:21.49 ID:rNqWj2dY0.net] やっぱ例外というブツは、 アプリケーション領域においてプログラミがいろんなリソースを取り扱うようになった結果、 C言語流に関数の戻り値で起こり得る全てのエラーを網羅してチェックする方法が 現実的でなくなってきたから設けられたブツなので >自分の知らないライブラリの奥底からいつ投げられるかわからない例外(>>154 すなわち設計に対して想定外の事象が起きた知らせとしてが飛んでくるというのが基本的かつ本来的な姿 起こりえる全ての例外の処置を書かなければ設計とは言えない主義の人(>>149 )は 寧ろ例外の使用をやめてC言語的な書き方で全てのエラーをチェックすべき (他人様が作ったライブラリが例外を飛ばしてくるのは仕方が無いから全てcatchする
158 名前:デフォルトの名無しさん mailto:sage [2024/01/13(土) 14:15:12.02 ID:rNqWj2dY0.net] つなみにOSの内部ではすべてのリソースをOSが管理する前提なので例外の出る幕は無い OSの設計に対して想定外の事象がOS内部で起きるとかあり得ないじゃない レトロな(しかしメジャーな)OSがC++ではなくC言語で書かれ続けるのはそういう理由
159 名前:はちみつ餃子 mailto:sage [2024/01/13(土) 14:21:37.75 ID:3bve4IFf0.net] 何が返ってくるかわからん (ドキュメント化されていない) なら返却値の形になっていても正しく対処できないのは同じだろ。
160 名前:デフォルトの名無しさん mailto:sage [2024/01/13(土) 14:37:35.65 ID:b/trpwza0.net] 例外だとテストしないドキュメントにも書かないというモラルハザードがおきやすいとは言えるだろう 返り値はエラー体系を自分で定義しないといかんからそうはなりにくい まぁそれでも失敗を安易にfalseに丸めるどアホは多いけど
161 名前:デフォルトの名無しさん mailto:sage [2024/01/13(土) 15:22:27.34 ID:o+zGF69d0.net] >>157 >すなわち設計に対して想定外の事象が起きた知らせとしてが飛んでくるというのが基本的かつ本来的な姿 それ一般にはリリース後に起きちゃいけないことでは。プロダクトにもよるが防ぐ努力は必要だと思うがね。
162 名前:デフォルトの名無しさん (ワッチョイ 7291-Qz6p) mailto:sage [2024/01/14(日) 13:01:30.73 ID:H7tsxQrq0.net] >>138 全選択肢を同時に選ぶって意味に捉えられちゃったかな? そうじゃなくて、その選択肢自体が同時に適用すべきレベルのものじゃないと思うの 例外をキャッチするって決めたなら、そこには目的があるよね? 設計手順としては目的を決めてから例外を使おうって判断になるわけ その目的次第だよね?っていうのがD 目的がリソースリーク防止ならA Aのような目的を達成するために、目的範囲内でB デバッグ目的ならC 製品等で客の目に見せたくないなどの営業目的があるならCはダメで、のべつまくなしBというのもあるかもしれない
163 名前:デフォルトの名無しさん (ワッチョイ 7291-Qz6p) mailto:sage [2024/01/14(日) 13:06:09.91 ID:H7tsxQrq0.net] 大きな目で全工程トータルを考えると全部の選択肢を適用する必要があるし、適用のしどころが違うと思うってのが>>136 の真意でした
164 名前:デフォルトの名無しさん (ワッチョイ 7291-Qz6p) mailto:sage [2024/01/14(日) 13:12:37.16 ID:H7tsxQrq0.net] >>148 これが正しいかどうかはおいといて、人命に関わらないなら、自分はその考え方に賛成! 完璧にデバッグしろというのは自動車と医療機器など人命にかかわるものだね 重要度に応じて工数のかけ方が変わってくるので、すべてのソフトウエアで一概にこうしなさいとは言えないかな そういう意味ではD
165 名前:デフォルトの名無しさん (ワッチョイ 4d34-7Ntv) mailto:sage [2024/01/14(日) 15:16:56.65 ID:by9QQMRz0.net] >>162 ああ、なるほどね 分かりやすくありがとう、助かりました
166 名前:デフォルトの名無しさん mailto:sage [2024/01/15(月) 08:10:14.00 ID:Y8oMeLNI0.net] 人命にかかわらない場合であっても、末端の関数が投げる例外の種類を見落としただけでプログラム全体が いきなり落ちるのは勘弁してほしいし、それを防ぐために全部の関数が投げる例外の種類を全部把握するというのも 無理ゲーに近い。 なので適当なレイヤーごとにざっくり std::exception をキャッチする造りにしてるな。例外の種類で選択したりはしない。
167 名前:デフォルトの名無しさん (ブーイモ MM22-7+/r) mailto:sage [2024/01/15(月) 11:54:06.38 ID:0QYW1wwzM.net] キャッチしてその後どうすんの?
168 名前:デフォルトの名無しさん mailto:sage [2024/01/15(月) 18:12:26.71 ID:FtZTeDOW0.net] 何するか思い付かないならPG辞めろ 貴様には向いてない
169 名前:デフォルトの名無しさん mailto:sage [2024/01/15(月) 18:20:04.00 ID:Y8oMeLNI0.net] >>167 そのtryブロックの処理が失敗したものとして処理を続ける。
170 名前:デフォルトの名無しさん (ワッチョイ 46ea-7+/r) mailto:sage [2024/01/15(月) 18:42:14.36 ID:Lgn9c/GO0.net] テストケース爆増じゃん
171 名前:デフォルトの名無しさん (ワッチョイ 6ecf-CdjJ) mailto:sage [2024/01/15(月) 19:20:39.72 ID:Y8oMeLNI0.net] なんで爆増?
172 名前:デフォルトの名無しさん mailto:sage [2024/01/15(月) 20:40:13.04 ID:Lgn9c/GO0.net] その失敗する処理の具体例言ってみて
173 名前:デフォルトの名無しさん mailto:sage [2024/01/15(月) 22:10:56.13 ID:Y8oMeLNI0.net] んでテストケース爆増の話は?処理の具体例次第で話が変わったりするとか?
174 名前:デフォルトの名無しさん (ワッチョイ 46ea-7+/r) mailto:sage [2024/01/15(月) 22:45:20.95 ID:Lgn9c/GO0.net] 依存関係のあるものに影響あるのは当たり前 原因不明の例外起こっても突き進むんだったら擬似的にそのケース作ってテストするわな普通は 出し渋るなら別にださなくていいよ 参考にならなさそうだし
175 名前:デフォルトの名無しさん (ワッチョイ 6ecf-CdjJ) mailto:sage [2024/01/15(月) 23:24:57.00 ID:Y8oMeLNI0.net] それはいったい何のテストなんだろう。原因不明の例外を首尾よくキャッチできるかどうかテストしろと言っているんだろうか。 そもそもそういう例外を想定するなら、スルーして影響範囲が広がる方がテストは厄介になると思うがなあ。
176 名前:デフォルトの名無しさん (ワッチョイ 11fb-5Qxc) [2024/01/15(月) 23:36:35.23 ID:rchiNbsm0.net] たとえば業務用のラベルプリンターでAPIが提供されてるとか とりあえず try ~ catch して「印刷中に不明なエラーが発生しました」みたいなまとめかたはあるかなー
177 名前:デフォルトの名無しさん [2024/01/23(火) 17:00:13.54 ID:kD0da0AW0.net] すみません。質問させて下さい。次のコードがMinGW-w64 g++ v13.2では --itrでエラーになります。わからないのはVisual studio 2022およびVisual StudioがサポートするClang LLVMでは通って正しく 実行しているように見えます。--itrの仕様がないのはMinGW-w64 g++v13.2が正しいのでしょうか?それともVisual Studioが正しいのでしょうか? #include <iostream> #include <unordered_set> using namespace std; int main() { unordered_set<int> us = { 1,2,3,4,5,6 }; for(auto itr = begin(us); itr != end(us); ++itr) cout << *itr << endl; auto itr = us.begin(); ++itr; ++itr; cout << *itr << endl; --itr; cout << *itr << endl; cin.get(); return 0; } MinGW-w64 g++ v13.2のエラー // error: no match for 'operator--' (operand type is 'std::__detail::_Node_iterator<int, true, false>')
178 名前:はちみつ餃子 mailto:sage [2024/01/23(火) 17:23:45.88 ID:MIeJSKFF0.net] >>177 unordered_set は forward iterator をサポートしているという規定がある。 https://timsong-cpp.github.io/cppwp/n3337/unord.set.overview#1 forward iterator は進めることは出来ても戻ることはできない。 この場合は operator-- がないのが正しい。 拡張してより高機能なライブラリを提供しても仕様に反するってわけではないけど マイクロソフトのドキュメントでも特に拡張しているという文面は見当たらないから あんまりあてにしないほうが良さそうには思う。 https://learn.microsoft.com/en-us/cpp/standard-library/unordered-set-class?view=msvc-170#iterator
179 名前:デフォルトの名無しさん [2024/01/23(火) 17:34:44.31 ID:kD0da0AW0.net] おお、ありがとうございます。
180 名前:デフォルトの名無しさん mailto:sage [2024/01/28(日) 11:36:45.25 ID:W0uCnQb30.net] >>173 横やが関数foo()で1つの例外が発生したらその時点のfoo()呼び出しに至る10個かそこらの関数が中断されるわけや すなわち関数bar()が 処理A→B→C→D→return の順で処理が進むことを気体しているところに、Bで呼び出している関数baz()がfoo()を呼び出している結果、foo()で例外を生じると 処理A→B→return という処理順に変更になる。こうなっても大丈夫なようにtry { 処理B } catch ((fooが投げる例外)& e) { (eに対する適切な処置) } を書かねばならず、 これが実は潜在的には処理A、B、C、Dのどこでも起き得るから厳密なことを言えば全てについて書かねばならず、 それがfoo()呼び出しに至る10個かそこらの関数それぞれについて行われねばならない。 検証もそんだけ組み合わせが増える。
181 名前:デフォルトの名無しさん mailto:sage [2024/01/28(日) 11:40:58.52 ID:W0uCnQb30.net] というわけでそんなの現実には不可能なので、現実的な処置としては ・ライブラリ製作者はなんか都合が悪い事が起きたら何でも呼び出し元に返す。 第1選択としてはエラーステータスを返すことを検討し、それではコードが煩雑になりすぎる場合は例外を投げて異常を知らせる ・ライブラリを使う人はライブラリが例外を投げない条件で使うことを心掛け、自前のコード内でtry { } catch() { }を極力しない という処置になるわ けや
182 名前:デフォルトの名無しさん (ワッチョイ 66cf-5eDQ) mailto:sage [2024/01/28(日) 12:02:32.93 ID:Gsm093HM0.net] catchしようがしまいが、例外が起きて 処理A→B→return となるのは同じだと思うが。 その場合の検証が必要だというならどっちも必要だろ。
183 名前:デフォルトの名無しさん (ワッチョイ 6d63-H5uA) mailto:sage [2024/01/28(日) 12:13:11.85 ID:W0uCnQb30.net] >>182 >catchしようがしまいが、例外が起きて 処理A→B→return となるのは同じだと思うが。 それは問題の認識がおかいし 例えば以下のコードにおいて、スレッドのゾンビを生じさせないためにはfuncB()をtry { } catch () { } は必須になる。 void bar() { funcA(); // スレッドxを起動 funcB(); // 中でbaz() → foo()の呼び出し funcC(); // スレッドxに停止シグナル発酵 funcD(); // スレッドxの終了待ち return; } このように一般に例外が飛んでくる関数にはcatchするかしないかの選択権など無い 例外安全なオブジェクト「だけ」で事が済んでいない限り、例外を受けると決めた時点でcatchせねばならない 一方、例外を生じないライブラリの使い方(関数の呼び出し方)を心掛けるかどうか。これなら選択肢がある
184 名前:デフォルトの名無しさん (ワッチョイ 6d63-H5uA) mailto:sage [2024/01/28(日) 12:14:54.75 ID:W0uCnQb30.net] 訂正orz 誤:例外安全なオブジェクト「だけ」で事が済んでいない限り、例外を受けると決めた時点でcatchせねばならない 正:例外安全なオブジェクト「だけ」で事が済んでいない限り、例外が飛んでくる想定であるならばcatchせねばならない
185 名前:デフォルトの名無しさん (ワッチョイ 797c-+np5) mailto:sage [2024/01/28(日) 12:19:26.10 ID:/bXkl1Cz0.net] >>183 それはfuncB()に失敗の可能性がある時に必ず必要な話だろ?例外どうこうじゃないじゃん funcB()が例外を投げずに古き良きintのエラーコードを戻り値で返す場合は何かが変わるの? まさか「funcBの戻り値をガン無視すればfuncCもfuncDも実行されてくれるから完璧!だから例外はクソ!」っていうゴミカスみたいな主張をしたいわけじゃないよね?
186 名前:デフォルトの名無しさん (ワッチョイ 66cf-5eDQ) mailto:sage [2024/01/28(日) 12:28:00.13 ID:Gsm093HM0.net] >>183 それはcatchが必要かどうかの話だろ。 catchしたらテストケースが増えるかどうかという話とはなんも関係がない。
187 名前:デフォルトの名無しさん mailto:sage [2024/01/28(日) 15:40:48.23 ID:JnoCOYDS0.net] そもそも未知の例外飛んできた時点でそれを通したライブラリの例外安全性が守られてるか怪しいと考えるべき
188 名前:デフォルトの名無しさん mailto:sage [2024/01/28(日) 17:01:39.99 ID:Gsm093HM0.net] 例外安全性を守るのに例外の種類やそれが既知か未知かは関係ないだろうが、 仕様に明記した例外以外は堰き止めるのが正解だろうなあ。
189 名前:◆QZaw55cn4c (ワッチョイ 3583-LgJ8) [2024/01/28(日) 20:27:29.75 ID:0TnCAHFI0.net] 思い立って結城さんのデザパタ(古いjava で記述)を総称型(テンプレート)もちゃんと使ってC++ に書き直しているけれども、 new/delete からptr::shared_ptr に書きなおすと、もう構造がわかりにくくなってしまってどうしようもない デザパタ=抽象クラスプログラミングは C++ ではオワコンなの? Visitor パターン new/delete: https://ideone.com/6d43LO スッキリ書けてきもちいい std::shared_ptr: https://ideone.com/oYzkxh 恐ろしい宣言の連発 >std::shared_ptr<Iterator<std::shared_ptr<Entry>>> iterator() { return std::make_shared<VectorIterator<std::shared_ptr<Entry>>>(v); } なんかもう書いてても意味不明 CONSTRUCTOR(CONSTRUCTOR *p) とかコピコン以外にもみたことのないコンストラクタが要求されるし
190 名前:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 2a3e-vdg+) mailto:sage [2024/01/28(日) 20:53:25.29 ID:hRRbWEE/0.net] >>189 スマートポインタを使わないバージョンも C++ 的にはすっきりしてない。 動的多態の必要が必要ないのに持つべきメンバ関数を強制するためだけに抽象クラスを使っていて不恰好に見える。 コンセプトの導入がだいぶん後回しになった C++ の問題でもあるんだが……。 設計理念が妥当かどうかはともかくとして、元が Java なら直訳めいた C++ への置き換えがすっきりと書けるはずがない。
191 名前:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 2a3e-vdg+) mailto:sage [2024/01/28(日) 21:08:52.58 ID:hRRbWEE/0.net] ざっと見た感じだと抽象クラスとして必要なのは Entry だけかな。 ジェネリックラムダが visitor パターンで使いやすいのでそういうのが使いやすいように配慮するといいかも。 std::visit が C++ での visitor パターンのお手本だよ。
192 名前:デフォルトの名無しさん (ワッチョイ b501-PlwZ) mailto:sage [2024/01/28(日) 22:46:18.85 ID:VLKT1lFt0.net] >>189 usingなりtypedefでエイリアス作れば? using Entry_Ptr = std::shared_ptr<Entry>;
193 名前:デフォルトの名無しさん (JP 0Hbd-DQL8) [2024/01/28(日) 23:17:29.01 ID:wkb3ctO/H.net] 面白そうだからちょっと書いてみた。大きな変更点はこんな感じ。 ・accept が受け取るのは単に Visitor の参照でいい。ここで shared_ptr を使う必要はない。 ・Visitor が受け取るのも File や Directory の参照でいい。 ・SizeVisitor もいらない。File と Directory はともに Entry の子クラスとして getSize() を実装してるんだから、無理に visitor パターンを使わなくても単に getSize() を呼べばいいだけ。 ・iterator() が返すのも VectorIterator の shared_ptr ではなく、単に VectorIterator を返せばいい。 全体的に使う必要がない場面で shared_ptr を使ってるのが目立ったと思う。 https://wandbox.org/permlink/ZBKbF5iMVpb7Looi だいぶすっきりしたんじゃない?