2015-04-19 13 views
7

Rozważmy następujący kod.doładowanie :: funkcja roli stable_vector nie zwraca przydzielonej pojemności

#include <string> 
#include <boost/container/stable_vector.hpp> 
#include <iostream> 

int main() 
{ 
    boost::container::stable_vector<std::string> vec; 
    vec.reserve(10); 
    std::cout << "capacity = " << vec.capacity() << '\n'; 
} 

On działa to (na g ++/Linux), wyjście jest:

pojemność = 4294967286 (to 2^32 - 10)

Gdybym zastąpić boost :: pojemnik :: stable_vector z std :: vector powyżej, wyjście jest:

pojemność = 10

wiem, może to również być pojemność = 20 lub pojemność = 64 lub cokolwiek, ale to nadal sane zachowanie.

Jaka pojemność() zwraca dla stable_vector, wydaje się być (2^32 - N), gdzie N jest żądaną pojemnością z wezwaniem do rezerwy(). Nie widziałem takiej definicji pojemności w dokumentach: http://www.boost.org/doc/libs/1_56_0/doc/html/boost/container/stable_vector.html#idp33067968-bb.

+0

Oczywisty błąd jest oczywisty. Wydaje się być wprowadzone w 1.54. –

Odpowiedz

10

To oczywisty błąd. Winowajcą jest this diff, który zmienił ten wiersz w capacity()

return (index_size ? (index_size - ExtraPointers + extra_capacity) : index_size); 

do

const size_type index_offset = 
    (ExtraPointers + extra_capacity) & (size_type(0u) - size_type(index_size != 0)); 
return index_size - index_offset; 

która została pomyślana jako "optimization", przypuszczalnie poprzez unikanie oddział.

Niestety, dwa bloki kodu nie są równoważne. Drugim z nich jest rzeczywiście równoważne

return (index_size ? (index_size - (ExtraPointers + extra_capacity)) : index_size); 
//        ^       ^

Więc zamiast dodawania extra_capacity (który jest 10 w danym przypadku), to odejmuje go.

Błąd został naprawiony w bagażniku Boost.Container, a poprawka powinna znajdować się w następnej wersji Boost.

+3

Przedwczesna optymalizacja jest zła. – Lingxi

+0

@Lingxi To jest kod biblioteki, więc niekoniecznie nazywam to "przedwczesnym". Ale niektóre pomiary powinny były zostać wykonane, ponieważ podejrzewam, że tego rodzaju rzeczy mogły zostać obsłużone przez nowoczesne kompilatory. –