Como hacer std :: operador del vector [] compilar hacer una comprobación de límites en DEBUG, pero no en la liberación

StackOverflow https://stackoverflow.com/questions/1290396

Pregunta

Estoy usando Visual Studio 2008.

Soy consciente de que std :: vector tiene comprobación de límites con la función en () y ha indefinido comportamiento si intenta acceder a algo usando el operador [] de forma incorrecta (fuera de rango).

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

El modo de liberación se compilará sin comprobación de límites para el operador [], por lo que el rendimiento no se degrada.

llegué a pensar en esto porque estoy migrando una aplicación que fue escrito utilizando Borland C ++ para Visual Studio y en una pequeña parte del código que tengo este (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] (de modo elemento 0 del vector tiene sólo un elemento). Este es un comportamiento indefinido, lo sé, pero Borland vuelve 0 aquí, VS está fallando. Me gusta el choque mejor que volver 0, así que si puedo conseguir más 'accidentes' de la std :: excepción out_of_range ser lanzado, la migración se completaría más rápido (por lo que expondría más errores que Borland estaba escondido).

¿Fue útil?

Solución

Visual Studio 2005 y 2008 ya no sale de comprobación en operator[] por defecto, en ambos de depuración y las versiones de lanzamiento.

La macro para controlar este comportamiento es _SECURE_SCL . Establecer en 0 para desactivar la comprobación de límites.

Su plan actual en VS2010 es deshabilitar la comprobación de límites por defecto en las versiones de lanzamiento, pero mantenerlo encendido en depuración. (La macro también se está renombrado a _ITERATOR_DEBUG_LEVEL. No sé si hay alguna documentación formal disponibles en él todavía, pero se ha mencionado aquí y aquí )

Otros consejos

Activar la bandera _GLIBCXX_DEBUG hacer comprobación de límites en contenedores STL, como se discute aquí: http://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode.html

He formulado esta demasiado prematuramente, pero les dejo la respuesta de todos modos, así que estoy compartiendo algunos conocimientos.

El STL implementado en Visual Studio ya hacer una comprobación de límites cuando se compila en modo de depuración. Esto se puede ver en la cabecera <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));
        }

lo que existe la comprobación de límites para la clase de vectores. Yo no miro a otros recipientes, pero estoy seguro de que ellos tienen el mismo mecanismo.

No tengo acceso a cualquier máquina Windows en este momento. Pero si miro en la implementación STL entregado con g ++ en mi Mac OS X de la máquina, 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); }

Sin verificación realizada, caso de que en el modo de depuración. Sin marcro _GLIBCXX_DEBUG está desprotegido aquí en este código.

Tenga una mirada en su propia implementación STL entregado con MSVC y ver lo que se hace. Si hay verificación se peformed en cualquier caso ... no tiene otra opción, pero utilizando al () .. :-(

C ++ define operador vector [] como no tirar excepción por el bien de la velocidad.

Le aconsejo que para probar la aplicación en la configuración de depuración durante un tiempo hasta que se gana la confianza de que los principales errores "ocultos" han ido.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top