本当に個人的メモ。
VC10 で C++0x の対応状況をメモりつつ実際に動かしているんですけれど,lambda expression とスタックフレームの関係があまり理解できてなかったので,WinDbg も動かしながらゴニョゴニョ。以下のコードでいぢってたんですけど,意味はまったくありません。
#include <iostream>
int
main(int argc, char* argv[]) {
char* ptr = nullptr;
char* foo = "abcde";
auto f = [](int a) {
return ++a;
};
for (ptr = foo; *ptr != '\0'; ++ptr) {
std::cout << *ptr << std::endl;
std::cout << f(foo - ptr) << std::endl;
}
return 0;
}
ここで WinDbg の結果は載せないけれども,f 呼び出し時のスタックフレームは,こんな感じで作られるのか。ふーん。
sample.exe!`anonymous namespace'::<lambda0>::operator()(int a) 行 8
sample.exe!main(int argc, char * * argv) 行 14 + 0x17 バイト
これまでは,スタックフレームと明示的な関数は,ほぼ同じもんとして考えることができたけれども,どのタイミングでフレームができるのか,これからはちと用心しないといけなさそう。スタックに積まれたアドレスから,別のアドレスを call するのと同じだから,おそらく機械語的には,関数ポインタと同じような感じで解析することになるんだと思う。呼び出し規則はどうなるんだろう。
後は,auto のような省略系の構文も保守する上では罠になりそうな感じ。少なくとも,auto が宣言されているその場で型を見ることができないから,作用しているオブジェクトの実装を見て,さらに推論規則を踏まえて判断することになる,と。
コンパイラが賢くなると,デバッグや保守のために自分も賢くならなくちゃいけないわけで,なんだか大変。新しい制御機構なんかは,コンパイル後のアセンブリを見ながら関連付け直さなきゃ。C++0x のコーディングはたしかに楽しいんだけれども,それは開発のメインじゃないし。
もっとも,コンパイル時のエラー検出(final とか)が豊富にそろったのは,防御的にプログラミングする上で,願ったりかなったりだったりする。こゆのを上手く開発プロセスに乗っけるためにも,総合的に見て,デバッグのノウハウと安全なコーディング作法を早めに固めておく必要がありそうです。問題は,趣味であれ仕事であれ,それが報われるのか(開発の効率が上がるのか)とゆことなんだけれども。ひとつ何か作ってみないと分かんないな,こりゃ。