1
我想我已經找到了一個G ++的錯誤,但我不確定。我無法解釋它。編譯不應該通過BAD代碼,但它確實。 g ++ - 4.5和g ++ 4.6 -std = C++ 0x在沒有任何警告的情況下傳遞此代碼。G ++編譯錯誤的STL代碼
由於編譯器認爲指向Bar對象的指針是Bar對象本身。 我瘋了。我花了很多小時纔得到這個bug。有沒有什麼技術可以防止這種bug?
爲代碼給出:
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); – 2012-01-10 19:16:02
@ DaneelS.Yaitskov - 我不太清楚爲什麼標準要求它是'type (x)'而不是'static_cast(x)',但這可能是導致std :: bind1st/std :: bind2nd被棄用的原因之一。 '在C++ 11中 –
Flexo
2012-01-10 19:18:57