Сообщение Re[3]: COW устарел, осторожнее с его использованием? от 24.08.2022 1:31
Изменено 24.08.2022 4:49 Андрей Тарасевич
Re[3]: COW устарел, осторожнее с его использованием?
Здравствуйте, pax123, Вы писали:
P>Здравствуйте, Андрей Тарасевич, Вы писали:
P>>>В чем проблема с COW?
АТ>>Проблема с COW не имеет никакого отношения к многопоточности. Проблема с COW заключается в том, что данные в `std::string` официально являются непрерывным массивом и спецификация `std::string` разрешает бесконтрольную раздачу итераторов/указателей/ссылок на этот массив. Это запросто может приводить к возникновению "висящих" итераторов/указателей/ссылок в таком многообразии однопоточных контекстов, что пытаться специфицировать правила инвалидации таких итераторов/указателей/ссылок — бесперспективное занятие.
P>Не понятно, чем в этом случае строка с COW отличается от строки без этого
Один из заезженных примеров, которые приводят в таком случае — это вызов оператора `[]`. Стандарт хочет, чтобы вызов `[]` даже для неконстантного объекта, сам по себе не приводил к расщеплению, т.е. к COPY. В частности, вот в таком примере
после вызова `a[0]` происходит расщеплению и объект `b` оказывается единственным владельцем исходных данных. Уничтожение `b` в конце блока приводит к тому, что после завершения блока `ptr` оказывается висящим указателем.
В С++03 пытались выдумывать какие-то более сложные правила, призванные объяснить пользователю, что "так делать нельзя". Но потом к С++11 просто плюнули и постулировали, что такой код не имеет права инвалидировать `ptr`. В спецификации `std::string` появилось простое и прямое требование 23.4.3.2/4.2
> 4 References, pointers, and iterators referring to the elements of a basic_string sequence may be invalidated by the following uses of that basic_string object:
> (4.1) Passing as an argument to any standard library function taking a reference to non-const basic_string as an argument.212
> (4.2) Calling non-const member functions, except operator[], at, data, front, back, begin, rbegin, end, and rend.
Вот это "except..." и поставило крест на COW.
P>Здравствуйте, Андрей Тарасевич, Вы писали:
P>>>В чем проблема с COW?
АТ>>Проблема с COW не имеет никакого отношения к многопоточности. Проблема с COW заключается в том, что данные в `std::string` официально являются непрерывным массивом и спецификация `std::string` разрешает бесконтрольную раздачу итераторов/указателей/ссылок на этот массив. Это запросто может приводить к возникновению "висящих" итераторов/указателей/ссылок в таком многообразии однопоточных контекстов, что пытаться специфицировать правила инвалидации таких итераторов/указателей/ссылок — бесперспективное занятие.
P>Не понятно, чем в этом случае строка с COW отличается от строки без этого
Один из заезженных примеров, которые приводят в таком случае — это вызов оператора `[]`. Стандарт хочет, чтобы вызов `[]` даже для неконстантного объекта, сам по себе не приводил к расщеплению, т.е. к COPY. В частности, вот в таком примере
std::string a = "abc";
const char *ptr = a.data();
{
std::string b = a;
a[0];
}
// ...
после вызова `a[0]` происходит расщеплению и объект `b` оказывается единственным владельцем исходных данных. Уничтожение `b` в конце блока приводит к тому, что после завершения блока `ptr` оказывается висящим указателем.
В С++03 пытались выдумывать какие-то более сложные правила, призванные объяснить пользователю, что "так делать нельзя". Но потом к С++11 просто плюнули и постулировали, что такой код не имеет права инвалидировать `ptr`. В спецификации `std::string` появилось простое и прямое требование 23.4.3.2/4.2
> 4 References, pointers, and iterators referring to the elements of a basic_string sequence may be invalidated by the following uses of that basic_string object:
> (4.1) Passing as an argument to any standard library function taking a reference to non-const basic_string as an argument.212
> (4.2) Calling non-const member functions, except operator[], at, data, front, back, begin, rbegin, end, and rend.
Вот это "except..." и поставило крест на COW.
Re[3]: COW устарел, осторожнее с его использованием?
Здравствуйте, pax123, Вы писали:
P>Здравствуйте, Андрей Тарасевич, Вы писали:
P>>>В чем проблема с COW?
АТ>>Проблема с COW не имеет никакого отношения к многопоточности. Проблема с COW заключается в том, что данные в `std::string` официально являются непрерывным массивом и спецификация `std::string` разрешает бесконтрольную раздачу итераторов/указателей/ссылок на этот массив. Это запросто может приводить к возникновению "висящих" итераторов/указателей/ссылок в таком многообразии однопоточных контекстов, что пытаться специфицировать правила инвалидации таких итераторов/указателей/ссылок — бесперспективное занятие.
P>Не понятно, чем в этом случае строка с COW отличается от строки без этого
Один из заезженных примеров, которые приводят в таком случае — это вызов оператора `[]`. Стандарт хочет, чтобы вызов `[]` даже для неконстантного объекта, сам по себе не приводил к расщеплению, т.е. к COPY. В частности, вот в таком примере
для полноценной работы COW после вызова `a[0]` должно происходить расщепление, в результате которого объект `b` окажется единственным владельцем исходных данных. Уничтожение `b` в конце блока приведет к тому, что после завершения блока `ptr` окажется висящим указателем.
В С++03 пытались выдумывать какие-то более-менее сложные правила, призванные объяснить пользователю, что "так делать нельзя". Но потом к С++11 просто плюнули и постулировали, что такой код не имеет права инвалидировать `ptr`. В спецификации `std::string` появилось простое и прямое требование 23.4.3.2/4.2
> 4 References, pointers, and iterators referring to the elements of a basic_string sequence may be invalidated by the following uses of that basic_string object:
> (4.1) Passing as an argument to any standard library function taking a reference to non-const basic_string as an argument.212
> (4.2) Calling non-const member functions, except operator[], at, data, front, back, begin, rbegin, end, and rend.
Вот это "except..." и поставило крест на COW.
P>Здравствуйте, Андрей Тарасевич, Вы писали:
P>>>В чем проблема с COW?
АТ>>Проблема с COW не имеет никакого отношения к многопоточности. Проблема с COW заключается в том, что данные в `std::string` официально являются непрерывным массивом и спецификация `std::string` разрешает бесконтрольную раздачу итераторов/указателей/ссылок на этот массив. Это запросто может приводить к возникновению "висящих" итераторов/указателей/ссылок в таком многообразии однопоточных контекстов, что пытаться специфицировать правила инвалидации таких итераторов/указателей/ссылок — бесперспективное занятие.
P>Не понятно, чем в этом случае строка с COW отличается от строки без этого
Один из заезженных примеров, которые приводят в таком случае — это вызов оператора `[]`. Стандарт хочет, чтобы вызов `[]` даже для неконстантного объекта, сам по себе не приводил к расщеплению, т.е. к COPY. В частности, вот в таком примере
std::string a = "abc";
const char *ptr = a.data();
{
std::string b = a;
a[0];
}
// ...
для полноценной работы COW после вызова `a[0]` должно происходить расщепление, в результате которого объект `b` окажется единственным владельцем исходных данных. Уничтожение `b` в конце блока приведет к тому, что после завершения блока `ptr` окажется висящим указателем.
В С++03 пытались выдумывать какие-то более-менее сложные правила, призванные объяснить пользователю, что "так делать нельзя". Но потом к С++11 просто плюнули и постулировали, что такой код не имеет права инвалидировать `ptr`. В спецификации `std::string` появилось простое и прямое требование 23.4.3.2/4.2
> 4 References, pointers, and iterators referring to the elements of a basic_string sequence may be invalidated by the following uses of that basic_string object:
> (4.1) Passing as an argument to any standard library function taking a reference to non-const basic_string as an argument.212
> (4.2) Calling non-const member functions, except operator[], at, data, front, back, begin, rbegin, end, and rend.
Вот это "except..." и поставило крест на COW.