Biblioteca padrão C ++ e coletor de lixo Boehm

Eu quero desenvolver um aplicativo C ++ multi-threaded (onde eventualmente a maior parte do código C ++ seria gerado pelo próprio aplicativo, que poderia ser visto como uma linguagem específica de domínio de alto nível) no Linux / AMD64 / Debian com o GCC 4.6 (e provavelmente o mais recente padrão C ++ 11).

Eu realmente quero usar o coletor de lixo conservador de Boehm para todas as minhas alocações de heap, porque eu quero alocar com new(GC) e nunca me incomodo com delete . Estou assumindo que o GC de Boehm está funcionando bem o suficiente.

A principal motivação para usar C ++ (ao invés de C) é todos os algoritmos e collections std::mapstd::vector fornecidos pela biblioteca padrão C ++.

O GC de Boehm fornece um gc_allocator (em seu arquivo gc / gc_allocator.h).

Devo redefinir operator ::new como o de Boehm?

Ou devo usar todos os modelos de coleção com um argumento de modelo de alocador explícito definido para algum gc_allocator ? Eu não entendo exatamente o papel do segundo argumento de modelo (o alocador) para std :: vector ? É usado para alocar os dados internos do vetor ou para alocar cada elemento individual?

E quanto a std::string -s? Como tornar seus dados alocados no GC? Devo ter minha própria string, usando o template basic_string com gc_allocator ? Existe alguma maneira de obter as matrizes internas de char alocadas com GC_malloc_atomic não GC_malloc ?

Ou você aconselha não usar o Boehm GC com um aplicativo compilado pelo g ++?

Saudações.

Para responder parcialmente a minha própria pergunta, o seguinte código

 // file myvec.cc #include  #include  #include  #include  class Myvec { std::vector > _vec; public: Myvec(size_t sz=0) : _vec(sz) {}; Myvec(const Myvec& v) : _vec(v._vec) {}; const Myvec& operator=(const Myvec &rhs) { if (this != &rhs) _vec = rhs._vec; return *this; }; void resize (size_t sz=0) { _vec.resize(sz); }; int& operator [] (size_t ix) { return _vec[ix];}; const int& operator [] (size_t ix) const { return _vec[ix]; }; ~Myvec () {}; }; extern "C" Myvec* myvec_make(size_t sz=0) { return new(GC) Myvec(sz); } extern "C" void myvec_resize(Myvec*vec, size_t sz) { vec->resize(sz); } extern "C" int myvec_get(Myvec*vec, size_t ix) { return (*vec)[ix]; } extern "C" void myvec_put(Myvec*vec, size_t ix, int v) { (*vec)[ix] = v; } 

quando compilado com g++ -O3 -Wall -c myvec.cc produz um arquivo de object com

  % nm -C myvec.o U GC_free U GC_malloc U GC_malloc_atomic U _Unwind_Resume 0000000000000000 W std::vector >::_M_fill_insert(__gnu_cxx::__normal_iterator > >, unsigned long, int const&) U std::__throw_length_error(char const*) U __gxx_personality_v0 U memmove 00000000000000b0 T myvec_get 0000000000000000 T myvec_make 00000000000000c0 T myvec_put 00000000000000d0 T myvec_resize 

Portanto, não há nenhum malloc simples ou ::operator new no código gerado.

Então, usando gc_allocator e new(GC) eu aparentemente posso ter certeza que plain ::opertor new ou malloc não é usado sem meu conhecimento, e eu não preciso redefinir ::operator new


adendos (janeiro de 2017)

Para referência futura (graças a Sergey Zubkov por mencioná-lo no Quora em um comentário), veja também n2670 e e suporte a garbage collection (como std :: declare_reachable , std :: declare_no_pointers , std :: pointer_safety etc …) . No entanto, isso não foi implementado (exceto no modo trivial mas aceitável de torná-lo um não operacional) no GCC atual ou Clang, pelo menos.