Your SlideShare is downloading. ×
0
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
私とC++ in 例外安全day
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

私とC++ in 例外安全day

833

Published on

0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
833
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
1
Comments
0
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. 私とC++ In 例外安全Day
  • 2. 自己紹介 石川達也 株式会社Codeer代表取締役 C, C++, C#, Java
  • 3. Exceptional C++ 読書会で 常識のある人間です。
  • 4. Exceptional C++ 読書会で 常識のある人間です。 ・gotoを使わない。
  • 5. Exceptional C++ 読書会で 常識のある人間です。 ・gotoを使わない。 ・Duff‘s deviceなどもっての 外。
  • 6. Exceptional C++ 読書会で 常識のある人間です。 ・gotoを使わない。 ・Duff‘s deviceなどもっての 外。 ・VC++をDisらない。
  • 7. 今日は、 体験談を語らせてもらいます。 参考にするもよし、 マサカリ投げるもよし。 (優しく)
  • 8. アジェンダ ・例外 ・テンプレート活用例 ・関数ポインタキャスト ・アロケータ記憶 ・AOPもどきログ
  • 9. 例外 ・リソース系 ・プログラムミス系
  • 10. 例外 注)OutOfMemory 場合によって・・・ リソース系 or プログラムミス系
  • 11. 例外に関する姿勢 ・リソース系 FileIO 他の機器との通信 例外安全に作ります。 最終的には、catchして適切に処 理。 て言うか、例外とは思っていない。
  • 12. 例外に関する姿勢 ・プログラムミス (ASSERT含む) 問題はこれ。
  • 13. 例外(プログラムミス) std::vector<int> buf; ・・・ buf[index] = 100; //範囲外とか。
  • 14. 例外(プログラムミス) swtich(val) { ・・・ default://予期せぬ値とか。 ASSERT(FALSE); break; }
  • 15. 例外(プログラムミス) 可能な限りの終了処理をして プロセスを停止させる。 注)お客様との調整が必須。
  • 16. 例外(プログラムミス) 堅牢性と正当性は相反する。
  • 17. 例外(プログラムミス) size_t index = ・・・; std::vector<int> buf; ・・・ ASSERT_DEAD(index < buf.size()); buf[index] = 100;
  • 18. 例外(プログラムミス) swtich(val) { ・・・ default: ASSERT_DEAD(FALSE); }
  • 19. 例外(プログラムミス) そのまま動作させると・・・ ・永続データを壊すかも。 ・原因特定困難な不具合になる。 ・使われない復帰コードで コードが腐敗し、 さらなる不具合を招く。
  • 20. 例外(プログラムミス) 潔く終了すると・・・。 ・変なデータができない。 ・不具合解析が楽。 ・コードはスッキリ。 ↓ 結果的にリリース品質が劇的に UP。
  • 21. 例外(プログラムミス) あ、 「この辺は無理に終了しなくて も・・・」とかは無し。 その切り分けは難しく、 だんだん、生き恥をさらす方向に 行くので。
  • 22. 次
  • 23. テンプレート活用例 ①関数ポインタキャスト
  • 24. ①関数ポインタキャスト FARPROC GetProcAddress( HMODULE hModule, LPCSTR lpProcName ); おなじみ、DLL関数取得。
  • 25. ①関数ポインタキャスト 関数のロードが面倒・・・。 typedef void (__stdcall *FuncType)(int value); FuncType Func = NULL; Func = (Func)GetProcAddress(h, “Func”);
  • 26. ①関数ポインタキャスト ちょっとしたユーティリティーを作っておく。 template<typename T> void GetEx(HMODULE hModule, LPCSTR name, T& func) { func = (T)GetProcAddress(h, name); } #define GETPROC(h, f) GetEx(h, #f, f)
  • 27. ①関数ポインタキャスト スッキリ! void (__stdcall *Func)(int value); GETPROC(h, Func);
  • 28. ①関数ポインタキャスト ついこないだも、 使っちゃいました。 →コードへ。 http://www.codeer.co.jp/tec hnical-notes/NativeAndNet
  • 29. ②アロケータ記憶 DLLで、ランタイム異なるこ とありますよね・・・? (゚◇゚) 共通にすれば済む話・・・。
  • 30. ②アロケータ記憶 そうすると、ヒープも 違うんですよね。 混ぜるな危険 Exe メモリ管理 dll メモリ管理
  • 31. ②アロケータ記憶 でも、動的なコンテナ 使いたいんです。
  • 32. ②アロケータ記憶 で、コンテナ作りました。 Σ⊂( ̄□ ̄~j
  • 33. ②アロケータ記憶 template<typename T> class ArrayAllocator { public: T* (__stdcall *New)(unsigned int size); void (__stdcall *Delete)(T* ptr); ArrayAllocator() : New(NewCore),Delete(DeleteCore){}
  • 34. private: static T* __stdcall NewCore(unsigned int size) { return new T[size]; } static void __stdcall DeleteCore(T* ptr) { if (ptr) { delete[] ptr; } } };
  • 35. //配列 template<typename T> class Array { ArrayAllocator<T> _heap; ・・・ }; //文字列 class WString { Array<WCHAR> _core; ・・・ };
  • 36. 入れ子もOK! struct Data { Array<int> ar; WString str; }; void _stdcall Func(Array<Data>& a) { //データを詰める }
  • 37. ②アロケータ記憶 { Array<Data> a; Func(a); } 抜けたら、それぞれの メモリ管理のdeleteが 呼ばれる。 Void Func(Array<Data>& a) { a.resize(100); a[99].ar.resize(100); a[99].str = L“abc”;
  • 38. ③AOPもどきでログを仕込む 関数の呼び出し順を ログ出力したことありますよね?
  • 39. ③AOPもどきでログを仕込む 全部に、いちいち仕込むのは面倒! 横断的(AOP)に処理したい!
  • 40. template <typename Ret, int fileNo, int lineNo> struct AOPLog { //DLL関数の型 typedef Ret (__stdcall *FuncType)(); //ログ static std::string& Log() { static std::string log; return log; } //DLL関数 static FuncType& Func() { static FuncType func; return func; } //ログ出力と呼び出し static Ret __stdcall Invoke() { Print(Log()); return Func(); } };
  • 41. //戻り値voidで特殊化 template <int fileNo, int lineNo> struct AOPLog<void, fileNo, lineNo> { typedef void(__stdcall *FuncType)(); static std::string& Log() { static std::string log; return log; } static FuncType& Func() { static FuncType func; return func; } static void __stdcall Invoke() { Print(Log()); Func(); } };
  • 42. //ログ入り関数ロード template<int fileNo, int lineNo, typename Ret> void MakeLog(HMODULE h, Ret (__stdcall *&func)(), LPCSTR name) { typedef AOPLog<Ret, fileNo, lineNo> T; if (s_logMode) { T::Func() = (T::FuncType)::GetProcAddress(h,name); T::Log() = funcName; func = T::Invoke; } else { func = (T::FuncType)::GetProcAddress(h,name); } }
  • 43. //今のを引数が必要分繰り返す。 //BOOST_PPとか。 //でヘルパマクロ #define LOG_GETEX(fileNo, h, f) MakeLog<fileNo, __LINE__>(h, f, #f) //使うところは、すっきり。 void (__stdcall *Func)(); LOG_GETEX(0, h, Func);
  • 44. そろそろ時間! ご清聴ありがとうございまし た。

×