1

I'm trying const_string lib that looks not bad, but it crashes at runtime with access violation(atomic_count, operator++()). The test code:

#include <boost/const_string/const_string.hpp>
#include <boost/const_string/concatenation.hpp>

typedef boost::const_string<wchar_t> wcstring;

class Test
{
private:
    const wcstring &s1;
    const wcstring &s2;

public:
    Test()
        : s1(L"")
        , s2(L"")
    {
    }

    const wcstring &GetS1()
    {
        return s1;
    }

    const wcstring &GetS2()
    {
        return s2;
    }
};


Test t;

int _tmain(int argc, _TCHAR* argv[])
{
    //Test t;
    wcstring t1 = t.GetS1(); // crashes here
    wcstring t2 = t.GetS2();

    return 0;
}

It crashes only if t is global. If I move declaration into main(), it's ok. System: VS 2010, boost v. 1.47.0

The question: Am I doing something wrong or is it problem of library / compiler? Can someone recommend a more stable implementation of immutable strings for C++?

lurscher
  • 25,930
  • 29
  • 122
  • 185
G0r
  • 13
  • 2

1 Answers1

6

Your instance of Test has initialized its reference data members as references to temporaries created from the literals L"".

Oops. The temporaries no longer exist by the time you try to use one of them in the copy constructor of wcstring at the line that crashes, so your references don't refer to anything.

I think boost::const_string should pretty much always be used by value, that's what it's for.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
  • I have to admit ignorance in this one – `const` ref *can* bind to a temporary and thus extends its life-time in the current scope. What’s the scope here? The constructor? If that were the case, `const` ref would behave like a normal reference. What are the rules? (Does this merit a new question?) – Konrad Rudolph Sep 02 '11 at 09:21
  • @Konrad: yes, it's the body of the constructor. 12.2/5, "A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits". This does make const reference data members slightly dangerous, I can't off-hand think of *any* situation in which you want a data member that's used in the constructor but nowhere else, so accidentally initializing them with a temporary almost guarantees something bad will happen at an undefined later date. – Steve Jessop Sep 02 '11 at 09:24
  • Thank you Steve, I see the problem now. – G0r Sep 02 '11 at 09:44
  • Too bad that this particular `const_string` constructor isn't explicit. – dalle Sep 02 '11 at 12:51
  • @dalle: maybe. It would stop people accidentally using a reference when they meant a value, but there might well be other uses where implicit conversion is needed. If a function takes `std::string`, it's kind of useful to be able to call it with a string literal instead with no cast, and although I haven't used `const_string` I assume the same holds there. If it was explicit then people could always write overloads for those functions, of course. I guess it depends whether you like weak typing - if not then you don't want anything to have non-explicit ctors. – Steve Jessop Sep 02 '11 at 12:54