Я знаю, что GCC использует COW (Copy-On-Write) для std::string
, что делает невозможным использование std::string
в многопоточной программе. Но насколько я знаю, С++ 11 запрещает реализацию с использованием COW, потому что потоки теперь определяются стандартом, а семантика перемещения в значительной степени устаревает, так как потребность в COW все равно.
Теперь GCC 4.6 реализует множество стандартов С++ 11. Тем не менее, похоже, что реализация по-прежнему использует семантику COW. Это было привлечено к моему вниманию случайными встречающимися таинственными seg-ошибками в многопоточном приложении, которое я написал. Я подтвердил, что это, по сути, проблема с COW с помощью следующего тестового кода:
#include <iostream>
#include <string>
#include <cassert>
#include <thread>
using namespace std;
int main()
{
std::string orig = "abc";
std::string copy = orig;
std::cout << (void*) orig.data() << ", " << (void*) copy.data() << endl;
assert(orig.data() == copy.data());
}
Изменить: Обратите внимание на включение заголовка <thread>
здесь, доказывая, что это программа С++ 11. И здесь ссылка на ideone, подтверждающая, что я говорю (по крайней мере для GCC 4.5.1, который использует идеон)
Я не помню, почему, но почему-то у меня создалось впечатление, что флаг std=c++0x
исключает семантику COW, но это не так. Утверждение в вышеприведенном коде успешное, даже с флагом -std = С++ 0x. Таким образом, в принципе, с GCC 4.6, std::string
по-прежнему непригоден в многопоточном приложении.
Есть ли способ отключить семантику COW? Или мне нужно использовать std::vector<char>
, пока GCC не установит это?