SlideShare a Scribd company logo
私とC++
In 例外安全Day
自己紹介
石川達也
株式会社Codeer代表取締役
C, C++, C#, Java
Exceptional C++ 読書会で
常識のある人間です。
Exceptional C++ 読書会で
常識のある人間です。
・gotoを使わない。
Exceptional C++ 読書会で
常識のある人間です。
・gotoを使わない。
・Duff‘s deviceなどもっての
外。
Exceptional C++ 読書会で
常識のある人間です。
・gotoを使わない。
・Duff‘s deviceなどもっての
外。
・VC++をDisらない。
今日は、
体験談を語らせてもらいます。

参考にするもよし、
マサカリ投げるもよし。
(優しく)
アジェンダ
・例外

・テンプレート活用例
・関数ポインタキャスト
・アロケータ記憶
・AOPもどきログ
例外
・リソース系

・プログラムミス系
例外
注)OutOfMemory
場合によって・・・

リソース系
or
プログラムミス系
例外に関する姿勢
・リソース系
FileIO
他の機器との通信
例外安全に作ります。
最終的には、catchして適切に処
理。
て言うか、例外とは思っていない。
例外に関する姿勢
・プログラムミス
(ASSERT含む)

問題はこれ。
例外(プログラムミス)

std::vector<int> buf;
・・・
buf[index] = 100; //範囲外とか。
例外(プログラムミス)

swtich(val) {
・・・
default://予期せぬ値とか。
ASSERT(FALSE);
break;
}
例外(プログラムミス)

可能な限りの終了処理をして
プロセスを停止させる。
注)お客様との調整が必須。
例外(プログラムミス)
堅牢性と正当性は相反する。
例外(プログラムミス)
size_t index = ・・・;
std::vector<int> buf;
・・・
ASSERT_DEAD(index < buf.size());
buf[index] = 100;
例外(プログラムミス)

swtich(val) {
・・・
default:
ASSERT_DEAD(FALSE);
}
例外(プログラムミス)
そのまま動作させると・・・
・永続データを壊すかも。
・原因特定困難な不具合になる。
・使われない復帰コードで
コードが腐敗し、
さらなる不具合を招く。
例外(プログラムミス)

潔く終了すると・・・。
・変なデータができない。
・不具合解析が楽。
・コードはスッキリ。
↓
結果的にリリース品質が劇的に
UP。
例外(プログラムミス)

あ、
「この辺は無理に終了しなくて
も・・・」とかは無し。
その切り分けは難しく、
だんだん、生き恥をさらす方向に
行くので。
次
テンプレート活用例

①関数ポインタキャスト
①関数ポインタキャスト

FARPROC
GetProcAddress(
HMODULE hModule,
LPCSTR lpProcName
);
おなじみ、DLL関数取得。
①関数ポインタキャスト
関数のロードが面倒・・・。
typedef void (__stdcall *FuncType)(int value);
FuncType Func = NULL;
Func = (Func)GetProcAddress(h, “Func”);
①関数ポインタキャスト
ちょっとしたユーティリティーを作っておく。
template<typename T>
void GetEx(HMODULE hModule, LPCSTR name,
T& func)
{
func = (T)GetProcAddress(h, name);
}
#define GETPROC(h, f) GetEx(h, #f, f)
①関数ポインタキャスト
スッキリ!
void (__stdcall *Func)(int value);
GETPROC(h, Func);
①関数ポインタキャスト
ついこないだも、
使っちゃいました。

→コードへ。
http://www.codeer.co.jp/tec
hnical-notes/NativeAndNet
②アロケータ記憶
DLLで、ランタイム異なるこ
とありますよね・・・?

(゚◇゚)
共通にすれば済む話・・・。
②アロケータ記憶
そうすると、ヒープも
違うんですよね。
混ぜるな危険
Exe
メモリ管理

dll
メモリ管理
②アロケータ記憶

でも、動的なコンテナ
使いたいんです。
②アロケータ記憶
で、コンテナ作りました。

Σ⊂( ̄□ ̄~j
②アロケータ記憶
template<typename T>
class ArrayAllocator
{
public:
T* (__stdcall *New)(unsigned int size);
void (__stdcall *Delete)(T* ptr);
ArrayAllocator() : New(NewCore),Delete(DeleteCore){}
private:
static T* __stdcall NewCore(unsigned int size)
{
return new T[size];
}
static void __stdcall DeleteCore(T* ptr)
{
if (ptr)
{
delete[] ptr;
}
}
};
//配列
template<typename T>
class Array
{
ArrayAllocator<T> _heap;
・・・
};
//文字列
class WString
{
Array<WCHAR> _core;
・・・
};
入れ子もOK!
struct Data
{
Array<int> ar;
WString str;
};
void _stdcall Func(Array<Data>& a)
{
//データを詰める
}
②アロケータ記憶
{
Array<Data> a;
Func(a);
}
抜けたら、それぞれの
メモリ管理のdeleteが
呼ばれる。

Void Func(Array<Data>& a)
{
a.resize(100);
a[99].ar.resize(100);
a[99].str = L“abc”;
③AOPもどきでログを仕込む

関数の呼び出し順を
ログ出力したことありますよね?
③AOPもどきでログを仕込む

全部に、いちいち仕込むのは面倒!
横断的(AOP)に処理したい!
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(); }
};
//戻り値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(); }
};
//ログ入り関数ロード
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);
}
}
//今のを引数が必要分繰り返す。
//BOOST_PPとか。
//でヘルパマクロ
#define LOG_GETEX(fileNo, h, f) 
MakeLog<fileNo, __LINE__>(h, f, #f)
//使うところは、すっきり。
void (__stdcall *Func)();
LOG_GETEX(0, h, Func);
そろそろ時間!
ご清聴ありがとうございまし
た。

More Related Content

More from Tatsuya Ishikawa

Infragistics Web Day 2017 - 継続的な開発を支える テスト自動化技術
Infragistics Web Day 2017 - 継続的な開発を支える テスト自動化技術Infragistics Web Day 2017 - 継続的な開発を支える テスト自動化技術
Infragistics Web Day 2017 - 継続的な開発を支える テスト自動化技術
Tatsuya Ishikawa
 
Stack2017 自動化困難な状況での活動方法
Stack2017 自動化困難な状況での活動方法Stack2017 自動化困難な状況での活動方法
Stack2017 自動化困難な状況での活動方法
Tatsuya Ishikawa
 
メタな感じのプログラミング(プロ生 + わんくま 071118)
メタな感じのプログラミング(プロ生 + わんくま 071118)メタな感じのプログラミング(プロ生 + わんくま 071118)
メタな感じのプログラミング(プロ生 + わんくま 071118)
Tatsuya Ishikawa
 
Dot netconf2017 - VS拡張
Dot netconf2017 - VS拡張Dot netconf2017 - VS拡張
Dot netconf2017 - VS拡張
Tatsuya Ishikawa
 
.Netconf
.Netconf.Netconf
価値あるシステムテスト自動化の実現By friendly
価値あるシステムテスト自動化の実現By friendly価値あるシステムテスト自動化の実現By friendly
価値あるシステムテスト自動化の実現By friendlyTatsuya Ishikawa
 
Stac2014 石川
Stac2014 石川Stac2014 石川
Stac2014 石川
Tatsuya Ishikawa
 
Bindingからframework elementを見つける
Bindingからframework elementを見つけるBindingからframework elementを見つける
Bindingからframework elementを見つける
Tatsuya Ishikawa
 
【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上
【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上
【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上
Tatsuya Ishikawa
 
Friendlyで始めるwindowsアプリシステムテスト自動化+内部使用技術解説
Friendlyで始めるwindowsアプリシステムテスト自動化+内部使用技術解説Friendlyで始めるwindowsアプリシステムテスト自動化+内部使用技術解説
Friendlyで始めるwindowsアプリシステムテスト自動化+内部使用技術解説
Tatsuya Ishikawa
 
Windowsアプリテスト自動化 [Friendly+delphi]
Windowsアプリテスト自動化 [Friendly+delphi]Windowsアプリテスト自動化 [Friendly+delphi]
Windowsアプリテスト自動化 [Friendly+delphi]
Tatsuya Ishikawa
 
Ride on azure~アイデアソン編~
Ride on azure~アイデアソン編~Ride on azure~アイデアソン編~
Ride on azure~アイデアソン編~Tatsuya Ishikawa
 
他言語との連携(ネイティブから動的言語まで)
他言語との連携(ネイティブから動的言語まで)他言語との連携(ネイティブから動的言語まで)
他言語との連携(ネイティブから動的言語まで)Tatsuya Ishikawa
 
Friendlyを使ったwindowsアプリテスト自動化
Friendlyを使ったwindowsアプリテスト自動化Friendlyを使ったwindowsアプリテスト自動化
Friendlyを使ったwindowsアプリテスト自動化Tatsuya Ishikawa
 

More from Tatsuya Ishikawa (16)

Infragistics Web Day 2017 - 継続的な開発を支える テスト自動化技術
Infragistics Web Day 2017 - 継続的な開発を支える テスト自動化技術Infragistics Web Day 2017 - 継続的な開発を支える テスト自動化技術
Infragistics Web Day 2017 - 継続的な開発を支える テスト自動化技術
 
Stack2017 自動化困難な状況での活動方法
Stack2017 自動化困難な状況での活動方法Stack2017 自動化困難な状況での活動方法
Stack2017 自動化困難な状況での活動方法
 
メタな感じのプログラミング(プロ生 + わんくま 071118)
メタな感じのプログラミング(プロ生 + わんくま 071118)メタな感じのプログラミング(プロ生 + わんくま 071118)
メタな感じのプログラミング(プロ生 + わんくま 071118)
 
Dot netconf2017 - VS拡張
Dot netconf2017 - VS拡張Dot netconf2017 - VS拡張
Dot netconf2017 - VS拡張
 
.Netconf
.Netconf.Netconf
.Netconf
 
価値あるシステムテスト自動化の実現By friendly
価値あるシステムテスト自動化の実現By friendly価値あるシステムテスト自動化の実現By friendly
価値あるシステムテスト自動化の実現By friendly
 
Stac2014 石川
Stac2014 石川Stac2014 石川
Stac2014 石川
 
Bindingからframework elementを見つける
Bindingからframework elementを見つけるBindingからframework elementを見つける
Bindingからframework elementを見つける
 
boost - std - C#
boost - std - C#boost - std - C#
boost - std - C#
 
【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上
【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上
【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上
 
Friendlyで始めるwindowsアプリシステムテスト自動化+内部使用技術解説
Friendlyで始めるwindowsアプリシステムテスト自動化+内部使用技術解説Friendlyで始めるwindowsアプリシステムテスト自動化+内部使用技術解説
Friendlyで始めるwindowsアプリシステムテスト自動化+内部使用技術解説
 
Windowsアプリテスト自動化 [Friendly+delphi]
Windowsアプリテスト自動化 [Friendly+delphi]Windowsアプリテスト自動化 [Friendly+delphi]
Windowsアプリテスト自動化 [Friendly+delphi]
 
Ride on azure~アイデアソン編~
Ride on azure~アイデアソン編~Ride on azure~アイデアソン編~
Ride on azure~アイデアソン編~
 
他言語との連携(ネイティブから動的言語まで)
他言語との連携(ネイティブから動的言語まで)他言語との連携(ネイティブから動的言語まで)
他言語との連携(ネイティブから動的言語まで)
 
Friendlyを使ったwindowsアプリテスト自動化
Friendlyを使ったwindowsアプリテスト自動化Friendlyを使ったwindowsアプリテスト自動化
Friendlyを使ったwindowsアプリテスト自動化
 
XP祭り2013-LT-Codeer
XP祭り2013-LT-CodeerXP祭り2013-LT-Codeer
XP祭り2013-LT-Codeer
 

私とC++ in 例外安全day