2015-04-19 6 views
7

Betrachten Sie den folgenden Code.boost :: stable_vector die Kapazität Mitglied Funktion gibt nicht die zugewiesene Kapazität

#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'; 
} 

Auf laufen diese (auf g ++/Linux), der Ausgang ist:

capacity = 4294967286 (das ist 2^32-10)

Wenn ich boost ersetzen :: Container :: stable_vector mit std :: vector oben, ist die Ausgabe:

Kapazität = 10

ich weiß es auch hätte Kapazität gewesen = 20 oder Kapazität = 64 oder was auch immer, aber das ist immer noch gesund Verhalten.

Welche Kapazität() für stable_vector zurückgibt, scheint (2^32 - N) zu sein, wobei N die mit einem Aufruf von reserve() angeforderte Kapazität ist. Ich habe in der Dokumentation keine solche Definition von Kapazität gesehen: http://www.boost.org/doc/libs/1_56_0/doc/html/boost/container/stable_vector.html#idp33067968-bb.

+0

Offensichtlicher Fehler ist offensichtlich. Scheint in 1.54 eingeführt zu werden. –

Antwort

10

Dies ist ein offensichtlicher Fehler. Schuld daran ist this diff, die diese Zeile geändert in capacity()

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

zu

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

, die als "optimization" bestimmt war, vermutlich durch einen Zweig zu vermeiden.

Leider sind die zwei Blöcke des Codes nicht gleichwertig. Die zweite zu

tatsächlich gleichwertig ist
return (index_size ? (index_size - (ExtraPointers + extra_capacity)) : index_size); 
//        ^       ^

Anstatt also das Hinzufügen extra_capacity (die 10 in Ihrem Fall ist), subtrahiert es.

Der Fehler wurde seither in den Stamm von Boost.Container behoben, und das Update sollte in der nächsten Version von Boost sein.

+3

Vorzeitige Optimierung ist böse. – Lingxi

+0

@Lingxi Das ist Bibliothekscode, also würde ich es nicht unbedingt "voreilig" nennen. Aber einige Messungen hätten gemacht werden sollen, weil ich vermute, dass diese Art von Dingen wahrscheinlich von modernen Compilern gehandhabt werden konnte. –

Verwandte Themen