C ++ std :: string Constructor - PullRequest
       18

C ++ std :: string Constructor

3 голосов
/ 10 октября 2008

любые мысли по этому поводу будут оценены:

std::string s1 = "hello";
std::string s2 = std::string(s1);

Теперь я ожидаю, что эти две строки будут независимыми, то есть я мог бы добавить "world" к s2, а s1 все равно будет читать "привет". Это то, что я нахожу в Windows и Linux, но при запуске кода на компьютере HP_UX кажется, что s2 и s1 - это одна и та же строка, поэтому изменение s2 меняет s1.

Звучит ли это абсолютно безумно, кто-нибудь видел что-нибудь подобное?

Ответы [ 5 ]

5 голосов
/ 10 октября 2008

Хотя я не мог воспроизвести точную ошибку OP, я столкнулся с подобной ошибкой в ​​компиляторах HP-UX aCC. Я написал об этом на досках HP и в итоге получил ответ от HP. В основном их версии 3.xx (3.70, 3.73, 3.67 и т. Д.) ACC испортили конструкцию std :: string. Нам пришлось перейти на версии 6.xx компилятора. Проблема, с которой мы столкнулись в то время, заключалась в том, что для машин PA-RISC не было компилятора 6.xx, а был только Itanium. Я считаю, что компилятор 6.xx был выпущен для PA-RISC в сентябре 2007 года.

Код, который вызывал проблему, был:

#include <iostream>
#include <string>

class S : public std::string  // An extension of std::string
{
public:
  explicit S(const char* s)
    : std::string(s)
  {
  }
};

class N     // Wraps an int
{
public:
  explicit N(int n)
    : _n(n)
  {}
  operator S() const   // Converts to a string extension
  {
    return _n == 0 ? S("zero") : (_n == 1 ? S("one") : S("other"));
  }
private:
  int _n;
};

int main(int, char**)
{
  N n0 = N(0);
  N n1 = N(1);

  std::string zero = n0;
  std::cout << "zero = " << zero << std::endl;
  std::string one = n1;
  std::cout << "zero = " << zero
            << ", one = " << one << std::endl;

  return 0;
}

Это была печать:
ноль = ноль
ноль = один , один = один

Другими словами, конструкция строки один из n1 полностью перекрывала другую строку (строка ноль).

ПРИМЕЧАНИЯ:
Чтобы увидеть версию компилятора, введите «aCC -V»
Чтобы увидеть тип машины, введите «uname -m» (9000/800 ==> PA-RISC, ia64 ==> Itanium)

3 голосов
/ 10 октября 2008

Это должно быть ошибкой. std :: string может делать строки со счетчиком ссылок в качестве своей реализации, но как только она будет изменена, она должна «разветвляться» на строку.

1 голос
/ 10 октября 2008

Это наверняка будет дефектом. Этот пример дословно из стандарта C ++:

string s1("abc");
string::iterator i = s1.begin();
string s2 = s1;
*i = ’a’;  // Must modify only s1
1 голос
/ 10 октября 2008

Изменяются ли две строки на самом деле по-разному, или вы используете какое-то другое сравнение (например, адреса, возвращаемые c_str ())?

Некоторые реализации строки не копируют всю строку при копировании, чтобы ускорить копирование длинных строк. Если вы попытаетесь внести изменение в один из них, то реализация должна скопировать строку и внести соответствующие изменения (в идеале как часть той же операции).

1 голос
/ 10 октября 2008

Это звучит как ошибка для меня. Может кто-нибудь еще, у кого есть доступ к HP / UX, повторить это?

Вы говорите, что эта программа отображает одинаковый текст в обеих строках?

#include <stdio.h>
#include <string>

int main () 
{
    std::string s1 = "hello"; 
    std::string s2 = std::string(s1);   // note: std::string s2( s1); would reduce the number of copy ctor calls

    s2.append( ", world");

    printf( "%s\n", s1.c_str());
    printf( "%s\n", s2.c_str());
}
...