私はG ++バグを見つけたと思いますが、わかりません。私はそれを説明することはできません。コンパイルはBADコードを渡すべきではありません。 g ++ - 4.5およびg ++ 4.6 -std = C++ 0xは、このコードを警告なしで渡します。G ++は間違ったSTLコードをコンパイルします
これは、BarオブジェクトへのポインタがBarオブジェクトそのものだと考えています。 私は狂っています。私はバグを取得するために多くの時間を費やしました。この種のバグから保護する方法はありますか?
不正コードが得られます。
g++-4.6 for_stackoverflow.cpp && ./a.out
address of bar in main() 0xbff18fc0
Foo 0x9e80008 Bar 0xbff18fec
Foo 0x9e80028 Bar 0xbff18fec
Foo 0x9e80048 Bar 0xbff18fec
end
ソースコード:
#include <iostream>
#include <list>
#include <iomanip>
#include <algorithm>
#define BAD
using namespace std;
class Bar;
class Foo {
public:
virtual void tick(Bar & b) {
cout << "Foo " << this << " Bar " << setw(14) << (&b) << endl;
}
};
class Bar : public list<Foo*> {
};
int main() {
Bar bar;
cout << "address of bar in main() " << &bar << endl;
bar.push_back(new Foo());
bar.push_back(new Foo());
bar.push_back(new Foo());
#ifdef GOOD
for_each(bar.begin(), bar.end(), bind2nd(mem_fun(&Foo::tick), bar));
#elif defined(BAD)
for_each(bar.begin(), bar.end(), bind2nd(mem_fun(&Foo::tick), &bar));
#else
#error "define GOOD xor BAD"
#endif
cout << "end" << endl;
return 0;
}
bind2ndの引数の型は実際の引数の型から推論されています。そして、それはチェックと注意を払わずに別のものに急激に変換されます。これは本物の落とし穴です:(。次のようにchar x; float f; f = *((float *)(void *)&x); –
@ DaneelS.Yaitskov - 標準では、 'static_cast(x)'の代わりに 'std :: bind1st'/'std :: bind2nd'が廃止される理由の1つと考えられます'C++ 11で –
Flexo