c++ visual-studio-2008 bounds-checker

c++ - Cómo hacer que el operador de std:: vector[] compile haciendo verificaciones de límites en DEBUG pero no en RELEASE



visual-studio-2008 bounds-checker (5)

Estoy usando Visual Studio 2008.

Soy consciente de que std :: vector tiene límites de verificación con la función at () y tiene un comportamiento indefinido si intenta acceder a algo usando el operador [] incorrectamente (fuera de rango).

Tengo curiosidad si es posible compilar mi programa con la verificación de límites. De esta manera, el operador [] usaría la función at () y lanzaría un std :: out_of_range siempre que algo esté fuera de los límites.

El modo de lanzamiento se compilaría sin límites, buscando el operador [], de modo que el rendimiento no se degrade.

Me puse a pensar en esto porque estoy migrando una aplicación que se escribió usando Borland C ++ a Visual Studio y en una pequeña parte del código tengo esto (con i = 0, j = 1):

v[i][j]; //v is a std::vector<std::vector<int> >

El tamaño del vector ''v'' es [0] [1] (por lo tanto, el elemento 0 del vector tiene solo un elemento). Este es un comportamiento indefinido, lo sé, pero Borland está devolviendo 0 aquí, VS se está estrellando. Me gusta el bloqueo mejor que devolver 0, por lo que si puedo obtener más ''errores'' por la excepción std :: out_of_range que se está lanzando, la migración se completará más rápido (por lo que expondría más errores que Borland estaba escondiendo).


C ++ define el operador vectorial [] como no lanzar una excepción por motivos de velocidad.

Le aconsejo que pruebe la aplicación en Configuración de depuración por un tiempo hasta que adquiera confianza de que los principales errores "ocultos" desaparecieron.



No tengo acceso a ninguna máquina de Windows en este momento. Pero si veo la implementación de STL entregada con g ++ en mi máquina mac os x, desde /usr/include/c++/4.0.0/bits/stl_vector.h:

// element access /** * @brief Subscript access to the data contained in the %vector. * @param n The index of the element for which data should be * accessed. * @return Read/write reference to data. * * This operator allows for easy, array-style, data access. * Note that data access with this operator is unchecked and * out_of_range lookups are not defined. (For checked lookups * see at().) */ reference operator[](size_type __n) { return *(begin() + __n); }

No se realizó ninguna comprobación, aunque el evento está en modo DEBUG. No se marcó _GLIBCXX_DEBUG marcro aquí en este código.

Eche un vistazo a su propia implementación de STL entregada con MSVC y vea lo que se hace. Si no se realiza ninguna verificación en cualquier caso ... no tiene más remedio que usar at () .. :-(


Pregunté esto demasiado prematuramente, pero de todos modos estoy publicando la respuesta, así que estoy compartiendo algunos conocimientos.

El stl implementado en Visual Studio ya realiza comprobaciones de límites al compilar en modo de depuración. Esto se puede ver en el encabezado <vector> :

reference operator[](size_type _Pos) { // subscript mutable sequence #if _HAS_ITERATOR_DEBUGGING if (size() <= _Pos) { _DEBUG_ERROR("vector subscript out of range"); _SCL_SECURE_OUT_OF_RANGE; } #endif /* _HAS_ITERATOR_DEBUGGING */ _SCL_SECURE_VALIDATE_RANGE(_Pos < size()); return (*(_Myfirst + _Pos)); }

así que hay límites que comprueban la clase vectorial. No miré otros contenedores, pero estoy seguro de que tienen el mismo mecanismo.


Visual Studio 2005 y 2008 ya realizan controles de límites en el operator[] de forma predeterminada, tanto en las compilaciones de depuración como en las de lanzamiento.

La macro para controlar este comportamiento es _SECURE_SCL . Establézcalo en 0 para deshabilitar el control de límites.

Su plan actual en VS2010 es deshabilitar el control de límites por defecto en las versiones de lanzamiento, pero mantenerlo en depuración. (La macro también se renombra a _ITERATOR_DEBUG_LEVEL . No sé si todavía hay documentación formal disponible, pero se ha mencionado here y here )