【问题标题】:How can I workaround this Visual Studio compiler BUG?如何解决此 Visual Studio 编译器 BUG?
【发布时间】:2011-12-09 15:33:50
【问题描述】:

这是 Visual Studio 中“著名的”/vd2 错误,更多信息例如: 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;
}

【问题讨论】:

  • 也许我看错了,但链接的文章似乎说 /vd2 标志在 2010 年可能不需要?
  • 相信我,我试过了,没有它就无法使用虚拟继承部分。但是有了它,流析构函数就会失败。

标签: c++ visual-studio visual-c++ compiler-construction


【解决方案1】:

可以为您解决问题的随机想法:

  1. 不要使用 VS2010(坚持 2008 年发布)
  2. 使用不同的 STL(可能非常痛苦,具体取决于您的使用情况,但据我所知,问题来自 2010 年包含的 STL)。

我没有看到更多选项,除了将代码更改为不在构造函数/析构函数中使用 dynamic_cast 以及完全删除 /vd2 之外

【讨论】:

    【解决方案2】:

    我已经更新了我的博客文章,其中包含指向此讨论的链接和您的代码的改编版本以说明问题。我最初的“这似乎工作正常”的结论仍然成立,因为在 Gtk 中我还没有崩溃,但问题显然仍然存在并且可能随时出现。

    因为您的代码是重现问题的简化示例,所以我无法针对您的具体情况提供解决方法,除非您可能不想做一些事情(更改您的编译器,不要使用 dynamic_cast 等)

    据我了解,/vd2 和部分标准库不兼容。您将无法按照您想要的方式进行这项工作。你需要放弃其中一个。

    编辑:您编辑了您的问题,建议将 sstream 包装到不使用 /vd2 编译的不同翻译单元中,并修改您的代码以使用该包装器。这将为您提供两个或多个使用影响二进制接口的不同标志编译的翻译单元。您正在尝试通过使用实现定义和脆弱的方法来解决编译器错误。虽然它可能有效,但我不会相信它。

    【讨论】:

    • 谢谢,我现在正在考虑流包装器,请参阅我更新的问题
    • 我们使用glibmm,很多类都继承自Glib::Object,并且实现以“class GLIBMM_API Object : virtual public ObjectBase”开头,所以这些类需要/vd2开关
    猜你喜欢
    • 2010-11-26
    • 2021-12-10
    • 2014-06-11
    • 1970-01-01
    • 2011-04-09
    • 2013-04-24
    • 2020-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多