C++相談室 part153
■ このスレッドは過去ログ倉庫に格納されています
>>287
> ソフトウェアの良い設計というのは
> 結果的に破綻も漏れも無く抽象化できていればおk
そうだね。ただ、具体的にどんなノウハウを与えれば、>>288の言うスーパーマンを生み出すかってのが次の疑問だろうな。
自分はOOP、TDDあたりのノウハウが身につけば余裕だと思っているが。 OOPは物事を整理する仕組みは提供してくれるが
どう整理をつけるかはやっぱ設計者のセンスに委ねられたままやんけ
実際>>287にゼロベースで的確に答えることは難しい
TDDは設計を検証する仕組みは提供してくれるが以下略
んまーテストケースをいっぱい書くというのは
物事簡潔に済ませる習慣が身につく良い経験かも試練、 >>293
> OOPは物事を整理する仕組みは提供してくれるが
> どう整理をつけるかはやっぱ設計者のセンスに委ねられたままやんけ
その通り。だからこそ、そのセンスを磨かせるためにTDDもセットで紹介してみた。
まず、自分の設計が正しいか妥当性確認する手段も無いと間違ったオブジェクト指向が身に付く恐れがあるからね。
結局のところ、個々のセンスを磨かせないと駄目だが...センスを磨かせる環境を整えるのはリーダーの役割だと思う。
何もない状態でセンスで何とかせよ、よりは改善が期待できるよ。 コンパイラの都合というよりかはcとの互換性とランタイム速度優先のための仕様によるものだろう。
てかむしろもっとコンパイラの都合考えたらもう少しまともな仕様になっとるわ。 スーパーマンはある種の天才で、体系的に天才を教育する方法はないと思う。特に今現在の教育は全体の平均値を上げる事に主眼を置いているから。
大多数がほどほど幸せになる方法としてある程度うまくいってたけど、極少数が全体に絶対的な影響を及ぼすソフトウェアの世界だと効率の悪さが目立ってくるよね。
天才を見つけておいて必要な時に協力してもらうしかないんじゃないかな。全てにおいて天才はいないし来てもくれないので、得意分野では天才的みたいな奴と仲良くしておくぐらいか 体系的に天才を教育する方法
ってのは実は簡単で、C++をやらせればいい それは教育する方法ではなく
多数の中から天才を見つける方法なのでは? プログラムの才能のある人材を発掘する方法は、以前だとLispかHaskellをやらせるのが定番だったけど今はどうなのかね? まずクソ企業で天才が居座るメリット無くね?
誰かが頑張ってくれるだろうみたいな雑魚集団と仕事したくねーわ。 >>296
天才とは言っていない
ttp://equallove-2017.blog.jp/archives/24499215.html
ttp://equallove-2017.blog.jp/archives/24508935.html
ttps://star.programming-study.com/
2020年10月17日放送分
TK-80の産みの親?
元マイクロソフトでwindows95の開発に参加?
良く判らんけど
Windows95の生みの親に直撃!開発秘話やプログラミングの裏話、子どもたちに伝えたい思いを告白 >>301
誰かが頑張ってくれるだろうみたいな雑魚がいない企業をおまえさんは知っているの? deleteで解放しようとするとたまに落ちるバグがあるのですが
try〜catchで囲っても、やっぱ落ちます。
これって例外で処理することはできないんでしょうか?
それともやばいバグ過ぎてつかまえられないだけなのでしょうか? >>307
これじゃダメなんでしょうか?
すみませんC++よくわかってなくて…
try{
delete p;
}catch(...){
std::cerr << "error!" << std::endl;
} >>308
pのデストラクタの中で何かが起きていて、そこで例外が投げられないから補足できないのでは?
それと経験的に、再現性の無いバグは、十中八九、未定義の記憶域を読むことで発生する。 >>309
デストラクタは何もないので
どこかでメモリ処理がおかしくなってるんでしょうね…
一旦、動くようにしてみたかったのですが、もうちょっと調べてみます。
ありがとうございました。 そういうときに役に立つのがprintfデバッグだろ
どの工程で起こったのかある程度目星がつく >>321
継承元の親クラスを何個も辿ってよく調べたら
コンストラクタの中で怪しいポインタにアクセスしている個所がありました。
おそらくこれが原因だと思います。
皆さん有難うございました。 デストラクタとdelete演算子はデフォルトでnoexceptなんで、
例外発生時点で異常終了してしまい、try〜catchじゃ捕まえられないそうだ。
https://cpprefjp.github.io/lang/cpp11/noexcept.html そういう問題じゃねえよ
不定のポインタは検出不能だ いや、今回の問題の解決のために書いたわけではなくて、
>>308のように書いても無駄だと伝えるために書いた。
そのあたり明示せずに書き込んですまん。 atexit()
exit()
で捕捉出来ないかな デバッガに頼るのは甘え
プロはprintfだけで正しくデバッグする! プロは logger 使うし
百歩譲っても使うのは fprintf の方 printfが使える環境ならな
そうでない場面がごまんとあるから
選択肢は多いに越したことはない 基本的にprintfデバッグの延長
制度化体系化されたprintfデバッグがログ取り
loggerはより高度なprintfデバッグであり、その基本がprintfデバッグになる
この変数を眺めりゃ万事OK という直感が涵養される
loggerの出力先が10万キロ離れたプリンタなこともある C#を作ったアンダース・ヘルスバーグもデバッガのステップ実行よりもprintfを使うってインタビューで言ってたな >>300
C のポインタ、特に関数ポインタ、とか
リカーシブ、とかで十分でしょう >>334
でも最初のうち、プログラムが小さいうちは、それが一番手っ取り早いですね printf デバッグは完成後に printf の行を消すと動かなくなったりするω 関数化やクラス化でプログラムを小さくするわけで、あんまり関係ないな
assertを使うときもそうだが、デバッグ用のコードに副作用を入れちまうのはヘボ以下 デバッグOffして弊害残すヤツは動作の仕組み把握出来てないだけだろ
>>336、まず貴様のコーディングセンスを磨いてから出直してこい青二才 非同期で動くブツ同士の通信はprintfデバッグ大活躍なのでは…
誰がいつ何を呼んで何を渡したのかと呼ばれたほうが本当に受け取ったのかがすぐワカル
printf消去忘れについては条件コンパイルを使えば良いし、
Ad-hocな追加ならいかに大量にやってもソースコード管理システムで安全に消すこともできるわけやし、 未定義動作踏んでるときとかにprintfを呼び出すことでたまたま動くようにできたりする
ということか >本当に受け取ったのかがすぐワカル
buffer flush しないと判らんし
flush すると勝手に改行する環境とかあるし
そこまで便利ってほどでもなくね
nonbuffered しろってか ここまでの話をまとめると
やはりprintfデバッグが最強、ということですね #ifdef DEBUG
#define PUTCHAR(a) (putchar(a), fputc(a, _fpDbg))
#else
#define PUTCHAR(a) (putchar(a))
#endif
PUTCHAR(*ptr++);
みたいなことをやれば デバッグ時だけ*ptr++ が二回評価されて結果は変わってしまう。 >>343
インライン関数に置き換えられるだろ
少しは頭使え >>344
そんなことは当たり前。
IQが低い人と話すとこれだから困る。 >>347
駄目な例を敢えて書いたんだ。
どうしてそれが分からないの、あなた達には?
IQが高い人には駄目な例が単なる例として出されたのだと分かるのに
ここの人達にはそれがわからない。 >>339
非同期なアプリでprintf使うとタイミングが変わることがあるから安心できんな
デバッガよりは遥かに良いけど >>336 が
「printf デバッグは完成後に printf の行を消すと動かなくなったりするω」
と書いていたが、>>340が指摘した理由だけではないので、
そうなる他の理由の1例を>>343で書いた。 これが考える力なんだよ。
マスコミを含めて「知識知識」と言う人が多いが、生まれつきの頭が悪いと
>>344 >>347 のような馬鹿な発想しか出来ないのでどうにもなら無い。
俺に比べれば、おまえが池沼の癖に。 マクロを使う必要性が全く感じられなくてリアリティがない >>351
おまえ自分のこと頭おかしいと思わないならかなり進んだ病気だな >>350
たぶんみんなは
そりゃマクロ使えば何でもありありだろ
そんなことでドヤるとかバカじゃねーの
って思ってる… >>335
printfデバッグを肯定するとは
ロートルの吹きだまり感かなりある printfごときで騒いでる方が精神いかれてんだろ。。 今はJTAGがあるので、そんなにお金がかからない。
それでも、プロセッサごとにデバッグ環境を用意できるわけないだろ!!というのが日本企業の現状なら、中韓に任せて野菜でも育てる道が効率よい。
中韓は用意できるし、売り切ることが出来る。
printfデバッグなんてインパール作戦と同じ。
物量が違いすぎる。 >>360
私のマザーボードの JTAG/IEEE1149.1 はどれですか? >>362
OS開発の場合は、専用のボードを用いることを視野に入れる。
それが無理なら、中韓に任せて撤退するべし。 #ifdef DEBUG
#define PUTCHAR(a) do{auto b=a;putchar(b), fputc(b, _fpDbg);}while(0)
#else
#define PUTCHAR(a) (putchar(a))
#endif
死ねザコw 教師が「こういうやり方はしてはなりません」と言っただけなのに、
生徒「そういう場合は、inline使えよ馬鹿教師」
という馬鹿生徒の集まり。
学級崩壊。 教師が「こういうやり方はしてはなりません」と言っただけなのに、
生徒A「そういう場合は、inline使えよ馬鹿教師」
生徒B「こういうやり方ならいいんだよ、死ねザコw」
教師「」 inline関数や、>>364のやり方が分かった上で教師は言っている。
それとも、おまえらの通った学校の教師はそんなことも分からない
くらい程度が低かったのか?
どこの学校だよ。 俺が通った学校の教師か
化学のおじいちゃん先生だったな
当時C++はまだ世に出てなかったから
マクロの使い方は知らなかっただろうな >>372
#define マクロはありますが、lisp 様仕様マクロはありません c++の文句をいって
cの話を延々はじめる
そしてどっちも言い尽くされた話
printfデバッグやってるじじいの特徴 >>372
C++が世に出る前っていつ頃かわかってる?
その頃のCを化学のおじいちゃん先生がやってると思ったの?
おまえさんでさえK&R Cなんか使えるのか? DxLib は printfDx で printf 推奨ω >>371 ではC++はまだ世に出てなかったからマクロの使い方は知らなかっただろうと言ってるのに
>>375 では化学のおじいちゃん先生がCなんてやってるわけないだろうと言っている
それではC++が世に出ててもその頃のC++なんておじいちゃん先生はやらなかったのでは。
だとすると >>371 はいったい何が言いたかったのか… >>377
同一人物なんだが君は何に見えたのかな?? >>379
K&R1 か K&R2 かを指定してください もちろん1よ
2なんて馬鹿言うわけねえだろ
何が言いたいの? おまえさんは >>341
>nonbuffered しろってか
別に
非同期要素同士のハンドシェークがうまく行っているかは
callerとcallerの呼び出し順序に崩れが無いことをメッセージの中身とともに確認できればほぼほぼ十分なので
printf()を呼んでから出力されるまでの時間はあんま拘る意味は無い 非同期な処理を観察するってのは非同期な処理が「失敗しているかもしれない」のを見つけ出さなきゃいけないってことだよね。
複数のスレッドが競合したりする場合もあるってことだよね。
printf は歳入可能でもないし、問題があるときは printf の処理も信用できないと思うんだけど。
信用できないけどバッファに溜まったまま吐き出されないということはなるべくないようにしたいって話でしょ。 printfが再入可能でないってどゆこと? strtokみたいに状態を持つのか? 単一スレッドでも再帰なんかで再入は発生しうる
関数内でクリティカルセクションなどを使ってスレッド同期するようにしていても状態を持つ作りだと同一スレッドからの再入で異常になることはある Cランタイムは通常スレッドセーフだよね
だから複数スレッドでprintfを読んだりerrnoを参照してもよい
Windowsの場合、_beginthreadで作成したスレッドはCランタイム安全、CreateThreadで作成したスレッドはCランタイム安全ではないとかいう話もあった >>385
今、リエントラント(再入可能)という言葉は余り聞かなくなっているが、
ハードウェアに密着したプログラムを書くときに、ハードウェア割り込みの
割り込みルーチンがまだ終わってないタイミングで、同じ割り込みが生じ、
同じルーチンが再帰的に呼び出されることがあり、そのような呼び出しに
対応しているものを「リエントラント」と呼ぶことがあった。
ただし、そのようなプログラムは複雑になりがちなので、ハードウェア
割り込みが生じ、割り込みルーチンがまだ終わってないタイミングで、
同じ割り込みを発生させる原因がもう一度発生しても、割り込みルーチン自体を
呼び出さないようにする手法が使われることが多かった、というか、
その様にプログラムすることが標準とされ、そのためにプログラマブル割り込み
コントローラなるものが、その役割を果たすモードを持っており、それが通常、
有効な状態にされていた。 >>388
一方、単一スレッドプログラムの場合、mallocの中からmallocが再帰的に呼び出される
ことはそもそもない。printfも同様。
なので、複数スレッドが動作している場合でも、各スレッドにおいては、
mallocやprintfが再帰的に呼び出されることはない。
そして、mallocを作る場合、Heapに関する重要データを読み書きする時、クリティカルセクション
のようなもので囲って、1つのスレッドだけが読み書きできるようにするような手法が使われる。
この場合、その区間を実行しているのは、最大で1スレッドのみであり、複数スレッドが
同時に実行することはない。
もちろん、malloc自体は同時に複数のスレッドが呼び出しても良いが、malloc内部で重要データ
の読み書きが行なわれるのは、必ず1スレッドのみで、それ以外のスレッドは待機させられる。
割り込みハンドラをリエントラントにする場合には、このようなクリティカルセクション的な
やり方は絶対に使えない。
まず、割り込みハンドラは、実際に実行しているのは1スレッドと言えば1スレッド。
割り込み自体が、1コアしかなかったZ80などにおいても有った概念でもあるし、それは当然であるが。 ■ このスレッドは過去ログ倉庫に格納されています