SlideShare una empresa de Scribd logo
1 de 44
私と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);
そろそろ時間!
ご清聴ありがとうございまし
た。

Más contenido relacionado

Más de 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
 
価値あるシステムテスト自動化の実現By friendly
価値あるシステムテスト自動化の実現By friendly価値あるシステムテスト自動化の実現By friendly
価値あるシステムテスト自動化の実現By friendlyTatsuya 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
 

Más de 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