Pimpl
実装を隠す手法としてPimplはメジャーな手法だと思うが、思わぬ罠が潜んでいてくそはまった。。
最初はARMのコンパイラが駄目なのかと思ったが、VC2005で試したところこちらでも意図しない挙動を見せてビビる。
簡単に説明すると、Pimplの実装クラスと同名のクラスが他のファイルでローカルクラスとしてstaticで静的に作られるとPimplクラスのvtblがぶっ壊れるというもの。
どのくらいやばいかというとPimplのデストラクタが呼ばれる瞬間にヌルポで死ぬ。
デストラクタまで行かないとかやばすぎるだろ。
名前を衝突しないようにすればもちろん大丈夫なのだが、ファイルローカルなクラスでもコンパイラが混乱するとは。
これって結構メジャーなバグなんかな。
他の人が勝手に同名のクラスを作ってるとやばいね。
以下VC2005のテストコード。
pimpl_class.h
#pragma once class base { public: base() {}; virtual ~base() {} virtual void foo() = 0; }; // 純粋仮想クラス. class derived : public base { protected: derived() {}; public: virtual ~derived() {} virtual void foo() = 0; static derived *create(); };
pimpl_class.cpp
#include <stdio.h> #include "pimpl_class.h" // local_classと同じ名前を付ける. class hoge : public derived { public: hoge() { printf("pimpl_class: hoge::ctor\n"); } virtual ~hoge() { printf("pimpl_class: hoge::dtor\n"); } void foo() { printf("pimpl_class: hoge::foo\n"); } }; derived *derived::create() { return new hoge(); }
local_class.cpp
#include <stdio.h> // 別のファイルに同名のPimplのhogeが居る. class hoge { public: int a; int b; hoge() { a = 0; b = 0; printf("local_class.cpp: hoge::ctor\n"); } ~hoge() { printf("local_class.cpp: hoge::dtor\n"); } void foo() { printf("local_class.cpp: hoge::foo\n"); } }; // staticで実体を定義する. //static hoge s_hoge; // こっちだとpimplクラスの実体が壊れる. void call_hoge_foo() { static hoge *s_hoge = new hoge; // こっちはlocalのhogeのctorがおかくなる. s_hoge->foo(); }
main.cpp
#include "pimpl_class.h" void call_hoge_foo(); int _tmain(int argc, _TCHAR* argv[]) { call_hoge_foo(); derived *p = derived::create(); p->foo(); delete p; return 0; }
staticで実体を定義した時の実行結果.
local_class: hoge::ctor local_class: hoge::foo local_class: hoge::ctor <---なぜかlocalのhogeが呼ばれる. <ここでエラーのダイアログ>
singleton的な作り方をした時の実行結果.
pimpl_class: hoge::ctor <---なぜかpimplのhogeが呼ばれる. local_class: hoge::foo <--ちゃんとlocalのfooがよばれている. pimpl_class: hoge::ctor pimpl_class: hoge::foo pimpl_class: hoge::dtor
localの方で全くstaticな実体を作らなければ問題は起こらないが
同名のクラスはあまり好ましくない状況だというのがなんとなくわかると思う。
C#みたいなクラス分割が使えればそもそもこんな問題で悩む必要はないんだけどなぁ。。
イテレータ
クラス変数再代入不可でなんとなく興味を失いつつあったXtalだが、
文法覚えるならFizzBuzzっしょってことで色々試す。
ドキュメントを見る限りpowerを計算する演算子がなくて困ったが、普通に書いても結構短くなるのに気がついた。
その後もちょろちょろ調べてたらtest_iter.xtalとかあったので見てみるとなんかtimesとかあんじゃん。
collectとかjoinとかmapとかもあるじゃん。
Ruby系と同じイテレータが充実してて俄然やる気が出てきた。
ヘルプのオーバービューにはそんなの書いてなかったので全く気がつかなかったぜ。
意気揚々とアナゴル鯖にアップしたら対応してなくて脂肪wwwwwwww
一瞬萎えそうになるが、仕事で使う分にはRuby見たいな感じで結構高速なスクリプトが使えるんだからこれは結構使えるんじゃないかなって気になってきた。
class変数の再代入
http://d.hatena.ne.jp/xtalco/searchdiary?word=Xtal%20class%ca%d1%bf%f4
禁止されてるって!
クラス変数でほにゃほにゃしたい時とか結構あると思うんだけどfilelocal変数使うしかないのか?
Xtalつこうてみた
元々DL出来る奴はVC8で簡単にコンパイルは出来てたけど、ちゃんと動作してなくて放置してたが
レジスタマシンでさらに速くなった(http://d.hatena.ne.jp/xtalco/)っぽいので、SVNで落としてみた。
今回からはVC9のプロジェクトしか同梱されてないのでそのままではビルドできなくて困る。
自分でVC8用のプロジェクト作ってサンプル動かしてみたら割りとすんなり動いた。以前動かなかったサンプルも動いたので謎すぎる。
AObenchもサンプルに含まれてたので動かしてみたが元がどれぐらいなのかわからないので比較しようがないw
文法をちゃんとおっかけながら見た感じだとRubyとC++とJavaScriptを足したような文法になってるね。これで結構速いというのが驚き。
ラムダ生成式と関数生成式の違いが良くわからない。
filelocalが見れないとかなのか?
意外といいかもしんないと思い始めたところで、classにはまる。
ヘルプにも書いてあるけどメソッド生成式はバッドノウハウ的な使用が文法的に可能なのはいかがなもんだろうか。もちろん例外が発生して動かないんだけども実行させないとわからなかったりするからなあ。
// なぜなら、methodは関数が作られた場所のthisを記憶せず、 // 呼び出し元のthisを使用するためです。 // トップレベルではthisは、filelocalですので、 // filelocalがthisとして渡されていることになります。
とあるが
filelocal::bar: method{"filelocal::bar".p;} //もしくは method bar{"filelocal::bar".p;}
とやってからヘルプにある例の受け取った無名methodを呼び出すのをやっても何も表示されない。
例外で落ちることはなくなったがとにかく表示されない。どゆこと!?
つか使えないならコンパイル時にエラーにして欲しい。
あとヘルプ読むとインスタンス変数の定義はわかるんだけどもクラス変数がわからない。
_(アンダースコア)をつけない変数がそうなのか?
でも代入すると例外で落ちるしなぁ。まじでわけわかんねw
他にもセカンダリキーとかよくわかんない。
class周りがまじでわからなすぎて泣きそう。。。
Xtal講習会とかやって欲しい。
RIPMAP
新人にRIPMAPは使えないんですかと聞かれ「何それ(MIPMAPを言い間違えるなんてかわいいなぁ)」と答えるなさけない先輩。
http://d.hatena.ne.jp/ototoi/20070814
対応してるハード見たことねぇ!
MIPMAPだとせいぜい4/3倍のサイズになるけどRIPMAPだと4倍すか。
実装自体は結構簡単そうだし効果も高そうだし、最近のビデオカードとかメモリがGB単位だし一応使えてもいいと思うんだけど。シェーダで無理して実装できなくも無いな。
OPEN PROGRAMING
S3TCとか超久しぶりに調べてて、そういえばOPEN PROGRAMING(MT Frameworkの人のサイト)にあったなと思い探したらなんかなくなってた。
でも一応WebArchiveには残ってるみたいでよかった。
宇治社中といいこってりやといいメガデモ(あかずきんちゃんのアイコンのとこ)のとこといい昔便利だったサイトが見れなくなるのは困るなー。
そういうサイトは本人が故意に削除した奴以外はプロバイダが独自に保管するとかやってほしいぜ。
アーッ!この時コードギアスでも世界を変えた責任は本人の意思とは別に重くノシかかるトカなんとか言ってイタゼ。ッテアニメなのカヨーッ!(第三世界の長井風)
だから自分は影響力とか大したことはないと思っていても己の意思ででサイトを消すことは無いと思う。