2015-04-19 10 views
7

Prendere in considerazione il seguente codice.boost :: La funzione membro della capacità di stable_vector non restituisce la capacità assegnata

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

In esecuzione di questo (su g ++/Linux), l'uscita è:

capacità = 4.294.967,286 mila (che è 2^32-10)

Se sostituisco boost :: contenitore :: stable_vector con std :: vector sopra, l'output è:

capacità = 10

so che potrebbe anche essere stato la capacità = 20, o la capacità = 64 o qualsiasi altra cosa, ma questo è ancora un comportamento sano.

Quale capacità() restituisce per stable_vector sembra essere (2^32 - N), N è la capacità richiesta con una chiamata a reserve(). Non ho visto una tale definizione di capacità nei documenti: http://www.boost.org/doc/libs/1_56_0/doc/html/boost/container/stable_vector.html#idp33067968-bb.

+0

Il bug ovvio è ovvio. Sembra essere introdotto in 1.54. –

risposta

10

Questo è un bug evidente. Il colpevole è this diff, che ha cambiato questa linea in capacity()

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

a

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

che è stato inteso come "optimization", presumibilmente evitando un ramo.

Sfortunatamente, i due blocchi di codice non sono equivalenti. La seconda è in realtà equivale a

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

Così, invece di aggiungere extra_capacity (che è 10 nel tuo caso), è sottratto esso.

Il bug è stato risolto nel bagagliaio di Boost.Container e la correzione dovrebbe essere nella prossima versione di Boost.

+3

L'ottimizzazione prematura è malvagia. – Lingxi

+0

@Lingxi Questo è il codice della libreria, quindi non lo chiamerei necessariamente "prematuro". Ma alcune misure avrebbero dovuto essere fatte, perché sospetto che questo tipo di cose probabilmente potrebbero essere state gestite dai moderni compilatori. –

Problemi correlati