Will std::basic_string destroy null termination every time?

70 views Asked by At

Recently, I update my compiler from gcc-4.3.x to gcc-7.x, and then meet an Assert exception for one of my tester.

The code looks like:

struct data {
    data() : _c(0) { ++CREATED; std::cout<<"data  CREATED +1"<<_c<<" addres: "<<&_c<<std::endl;}
    data(char c) : _c(c) { ++CREATED; std::cout<<"data  with C CREATED +1"<<_c<<std::endl;}
    data(const data& rhs) : _c(rhs._c) { ++COPIED; }
    ~data() { ++DESTROYED; std::cout<<"data  DESTROYED +1"<<_c<<std::endl;}

    char _c;

    static size_t CREATED;
    static size_t COPIED;
    static size_t DESTROYED;
};

size_t data::CREATED   = 0;
size_t data::COPIED    = 0;
size_t data::DESTROYED = 0;

void testStringReferenceCopiable() {
    typedef std::basic_string<data> data_str;
    std::cout<<"1"<<std::endl;
    data d[] = {'a', 'b', 'c'};
    std::cout<<"2"<<std::endl;
    data_str s( &d[0], 3 );
    std::cout<<"3"<<std::endl;
    data_str s2 = s;
    std::cout<<"4"<<std::endl;
    data_str s3;
    std::cout<<"5"<<std::endl;
    s3 = s;
}

For gcc7.x output looks like:

1
data(char c) CREATED +1a
data(char c) CREATED +1b
data(char c) CREATED +1c
2
data()  CREATED +1
~data()  DESTROYED +1
3
data()  CREATED +1
~data()  DESTROYED +1
4
data()  CREATED +1
~data()  DESTROYED +1
5
data()  CREATED +1
~data()  DESTROYED +1
~data()  DESTROYED +1c
~data()  DESTROYED +1b
~data()  DESTROYED +1a

For gcc4.3.x version, out put is:

data  CREATED +1
1
data  with C CREATED +1a
data  with C CREATED +1b
data  with C CREATED +1c
2
3
4
5
data  DESTROYED +1c
data  DESTROYED +1b
data  DESTROYED +1a

data  DESTROYED +1


Basically I can understand why it call Construct of data() every time, may because of null-terminator. But I cannot understand why it call the destructor method of data every time. Does anyone can give me a answer?

Thanks!

1

There are 1 answers

0
Drew Dormann On BEST ANSWER

GCC 5 changed std::basic_string to adhere to several new requirements that were introduced in C++11.

The change you are noticing is that "copy on write" was abandoned for std::basic_string in GCC 5. That is to say, copies of the same string must be distinct and not merely reference-counted.