Topic: Shared representation, was: STL and SGI and strings


Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1998/01/19
Raw View
Matt Austern <austern@isolde.mti.sgi.com> writes:

|>  "Bill Wade" <bill.wade@stoner.com> writes:
|>
|>  > >Which still disallow sharing, except if c_str copies the data, which
|>  > >is as inneficient.
|>  >
|>  > Why does c_str() disallow sharing?  It returns a pointer to const which
|>  > remains valid only until a non-const member of the string is called.
|>
|>  Ah, but that's exactly the point.  s1.c_str() returns a pointer that
|>  remains valid until a non-const member on s1 gets called.  Non-const
|>  members on copies of s1, though, are quite a different story.
|>
|>       const char* p1 = s1.c_str();
|>       string s2 = s1;
|>       s2[0] = '*';        // No non-const member of s1 has been called,
|>                           //  so p1 is still valid.  This means that
|>                           //  p1 may not point to a region of storage
|>                           //  that is controlled by s2.

No problem in any of the shared implementations I'm familiar with.
Calling operator[] on a non-const string causes that string to have a
unique representation, but normally, it does so by creating a new
representation for it, not for any of the other strings.

On the other hand, I'm pretty much convinced that without operator[]
returning a smart reference (illegal according to the standard), you
cannot really share implementation, at least not in a practical sense.
Consider the following code:

    #include <string>
    #include <iostream.h>

    string              s( "xyz" ) ;
    bool                modified( false ) ;

    void
    f()
    {
        modified = (s[ 1 ] != 'y') ;    // since s non-const, unshares rep.
    }

    bool
    g( string const& s1 , string const& s2 )
    {
        return s1[ 1 ] == (f() , s2[ 1 ]) ;
    }

    int
    main()
    {
        string              t( s ) ;    // provoke shared rep.
        cout << g( s , s ) << endl ;
    }

While I can't really imagine anyone writing such junk, replace the call
to f() in g by a thread preemption, and it becomes evident that a shared
representation cannot be used in threaded code.  (For that matter,
imagine that f() was used in the evaluation of the index of s2.)

Note that the above code IS undefined behavior according to the
standard.  In f(), I have called a non-const function, which invalidates
the reference returned by s1[ 1 ].  Still, there is nothing that would
signal this in the source of g.  It's an error waiting to occur.

In practice, I expect that in time, most implementations will follow the
SGI model, providing a standard string class without shared
representation, and another proprietary class which is actually usable.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient   e objet --
              -- Beratung in objektorientierter Datenverarbeitung
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]