How can I workaround this Visual Studio compiler B

2019-07-18 10:40发布

This is the "famous" /vd2 bug in visual studio, more information ex.: http://mcdougalljonathan.blogspot.com/2011/12/visual-c-2010-stdistringstream-crash-in.html or google for "visual studio vd2 gtkmm" keywords..

So I have to produce a release with a code that have a lot of these pattern below with VS2010. Looks like impossible, I have 10 days left. Any idea?

#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";
}

EDIT

I have an idea... So I want to replace every std::stream to a wrapper, for ex. std2::stream, where I dynamically allocate them to a smart ptr, and I compile that wrapper implementation without the /vd2 switch. I will try it on next day...

So I want something like this

// 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;
}

2条回答
一夜七次
2楼-- · 2019-07-18 10:52

I've updated my blog post with a link to this discussion and an adapted version of your code to illustrate the problem. My initial conclusion of "this seems to be working fine" still stands, as in Gtk hasn't crashed on me yet, but the problem is obviously still present and could manifest itself anytime.

Because your code is a simplified example to reproduce the issue, I cannot give a workaround for your specific case, except for things you probably won't want to do (change your compiler, don't use dynamic_cast, etc.)

From what I understand, /vd2 and parts of the standard library are incompatible. You won't be able to make this work the way you want. You'll need to ditch one or the other.

edit: You edited your question to propose wrapping the sstreams into a different translation unit compiled without /vd2 and modifying your code to use that wrapper. This would give you two or more translation units compiled with different flags that affect the binary interface. You are trying to work your way around compiler bugs by using implementation-defined and brittle methods. Although it might work, I wouldn't trust it.

查看更多
相关推荐>>
3楼-- · 2019-07-18 11:00

Random ideas that can resolve it for you:

  1. Don't use VS2010 (stick to 2008 for your release)
  2. Use a different STL (potentially very painful, depending on your usage, but from what I gather, the issue comes from the STL included in 2010).

I don't see many more options, short of changing the code to not use dynamic_cast in constructors/destructors, and removing the /vd2 altogether

查看更多
登录 后发表回答