这是 Visual Studio 中“著名的”/vd2 bug,更多信息例如: http://mcdougalljonathan.blogspot.com/2011/12/visual-c-2010-stdistringstream-crash-in.html 或谷歌搜索“Visual Studio vd2 gtkmm”关键字..
所以我必须使用 VS2010 生成一个包含以下大量模式的代码的版本。看来不可能了,我还有10天时间。有什么想法吗?
#include <iostream>
#include <sstream>
struct Object
{
virtual ~Object() {}
};
struct Base: virtual public Object
{
Base() :Object()
{
// upcast and downcast
Object* o = static_cast<Object*>(this);
Base* b = dynamic_cast<Base*>(o);
std::cout << " this: " << this << " after cast: " << b;
// should be the same address
if ( this != b)
std::cout << " check address: NOK";
else
std::cout << " check address: OK ";
}
};
struct Derived: public Base
{
int i;
};
int main()
{
Derived d;
std::cout << " end arrived: ";
std::stringstream* ss = new std::stringstream;
delete ss;
std::cout << "OK";
}
编辑
我有一个想法...所以我想将每个 std::stream 替换为包装器,例如。 std2::stream,我将它们动态分配给智能 ptr,并且在不使用 /vd2 开关的情况下编译该包装器实现。我第二天会尝试...
所以我想要这样的东西
// compile without /vd2
#include <sstream>
#include <iostream>
#include <boost/scoped_ptr.hpp>
namespace std2
{
class stringstream
{
public:
stringstream()
{
m_stream.reset(new std::stringstream);
}
template<typename T>
std::stringstream& operator<<(const T& param)
{
*m_stream << param;
return *m_stream;
}
std::string str() const
{ return m_stream->str(); }
private:
boost::scoped_ptr<std::stringstream> m_stream;
};
}
int main()
{
std2::stringstream stream;
stream << "DDDD" << std::endl;
std::cout << stream.str() << std::endl;
return 0;
}
可以为你解决的随机想法:
我没有看到更多的选择,除了更改代码以不在构造函数/析构函数中使用dynamic_cast,并完全删除 /vd2
我已经更新了我的博客文章,其中包含此讨论的链接以及用于说明问题的代码的改编版本。我最初的结论“这似乎工作得很好”仍然成立,因为 Gtk 还没有崩溃,但问题显然仍然存在,并且可能随时显现出来。
因为您的代码是重现问题的简化示例,所以我无法针对您的具体情况提供解决方法,除非您可能不想做的事情(更改编译器,不要使用dynamic_cast等)
据我了解,/vd2 和部分标准库不兼容。你将无法按照你想要的方式进行这项工作。您需要放弃其中之一。
edit:您编辑了您的问题,建议将流包装到不带 /vd2 编译的不同翻译单元中,并修改您的代码以使用该包装器。这将为您提供两个或多个使用影响二进制接口的不同标志编译的翻译单元。您正在尝试使用实现定义的脆弱方法来解决编译器错误。虽然它可能有效,但我不会相信它。