2010-03-05 12 views
11

Con STL :: vector:límites Desactivación de la comprobación de C++ vectores

vector<int> v(1); 
v[0]=1; // No bounds checking 
v.at(0)=1; // Bounds checking 

¿Hay una manera de desactivar la comprobación de límites sin tener que volver a escribir todo lo at()[]? Estoy usando la biblioteca GNU Standard C++.

Editar: Me cambió at()-[] en la zona donde yo sospechaba un cuello de botella, y reduce significativamente el tiempo de cálculo. Sin embargo, dado que iteraré entre desarrollar el código y ejecutar experimentos con él, me gustaría habilitar la verificación de límites durante el desarrollo y desactivarlo cuando ejecuto los experimentos de forma real. Creo que el consejo de Andrew es la mejor solución.

+6

¿Con qué fin? Puede haber una mejor manera. –

+0

Debería poder usar una expresión regular para reemplazar 'at()' por '[]', y establecer un punto de interrupción para ayudar a verificar que todas las instancias hayan sido reemplazadas. No es que ese deslizamiento sería un desastre, la preocupación es solo el rendimiento, ¿verdad? – Potatoswatter

+4

¿Por qué querrías hacer esto? Si su respuesta es el rendimiento, por favor dígame que ha perfilado y que este es su cuello de botella. Si ese es el caso, entonces sí, vuelva a escribir su at() s como '[]'. De lo contrario, déjalo estar. –

Respuesta

15

No. La comprobación de límites de std::vector::at está especificada por el estándar, y no hay una implementación de C++ conforme con el estándar que pueda desviarse de eso.

3

No es una forma estándar. Puede desactivar excepciones en su compilador. Puede hacer esto con gcc con -fno-exceptions.

Sin embargo, debe tener cuidado de hacerlo; sus bibliotecas (incluidas las bibliotecas estándar) pueden no funcionar bien con excepciones desactivadas. Verifique su documentación e hilos como this one on the gcc mailing list.

+0

No creo que este sea un buen enfoque, pero +1 para el enlace. – Potatoswatter

6

Quizás una mejor solución es usar [] y usar la implementación comprobada de la biblioteca estándar para la depuración.

23

Si realmente desea hacerlo (al menos para una comparación de perfiles rápido y sucio), esto va a funcionar si no tiene otra at() s

#define at(x) operator[](x) 

Y si desea mantener at() para el desarrollo y use operator[] en producción, solo envuélvalo en un #ifdef.

Y si tiene otras at() s siempre puede editar su archivo #include d <vector>.

+0

+1 Tarde a la fiesta, pero con excelentes consejos. Esta es definitivamente la forma rápida y sucia de hacer un perfil de algo. –

+0

+1 esto hubiera sido mi sugerencia – imallett

0

Si tiene patrones razonablemente consistentes de acceso (es decir,/no acceso aleatorio), en lugar de utilizar at() o [], un método para evitar la verificación de rango es el uso de iteradores, utilizando begin(), end() y advance() o mejor aún, a través de la uso de los algoritmos estándar.

Aunque esto no resuelve el problema de fondo de corregir at() haciendo gama de comprobar algunas implementaciones de la biblioteca estándar (MSVC) han comprobado iteradores para algunos tipos de generaciones

3

Basado en su comentario que le gustaría a su vez en la comprobación/fuera, se puede utilizar una función de plantilla envoltorio:

template <class T> 
inline typename T::reference deref(T &cont, typename T::size_type idx) 
{ 
#if BOUNDS_CHECK 
    return cont.at(idx); 
#else 
    return cont[idx]; 
#endif 
} 

template <class T> 
inline typename T::const_reference deref(const T &cont, typename T::size_type idx) 
{ 
#if BOUNDS_CHECK 
    return cont.at(idx); 
#else 
    return cont[idx]; 
#endif 
} 

usted tendría que modificar el código para permitir esto, pero una vez que lo tenía en su lugar se podría convertir obligado comprobar encendido o apagado como desee .

Lo que admitir que se ve un poco feo de empleo:

deref(vec, 10) = ...; 
2

concluir cuál es su propia clase de vectores en su propio espacio de nombres como "uncheckedvector", y anular el al() del tipo de vector base a utilizar el índice de la matriz.

Luego use "using uncheckedvector :: vector" que le permitirá anular todos sus usos del vector en todas partes. Sin embargo, esto no funcionará si usa tipos totalmente calificados en cualquier lugar.

+0

-1: nunca heredé de los tipos STL, carecen de destructores virtuales. – Joh

2

Utilice at() cuando siempre quiere comprobar. También tenga en cuenta que esto arroja una excepción en caso de error, por lo que es potencialmente recuperable. Si desea el acceso más rápido y sin marcar, use [], pero los algoritmos que lo usan deben probarse exhaustivamente porque el modo de falla es más severo (comportamiento indefinido).

Un par de aproximaciones a los límites de desarrollo de modo de comprobación para [] cuando se utiliza GCC en Linux:

Algún otro interesante debate: vector::at vs. vector::operator[]