2009-06-24 15 views
8

¿Puede una excepción std :: capturada tener alguna vez que() sea NULO?C++ excepciones, ¿qué() puede ser NULO?

¿Está la comprobación de e.what() debajo de la sobrecarga?

//... 
} 
catch (const std::exception& e) 
{ 
    std::string error; 
    if(e.what()) 
    error = e.what(); 
} 

Respuesta

13

El contenido de la cadena está definido por la implementación, así que supongo que la respuesta es sí.

Edit: Belay that. El estándar dice:

virtual const char* what() const throw(); 
5 Returns: An implementation-defined NTBS. 

Por lo tanto, debe devolver una cadena, no solo un puntero. Y una cadena no puede ser NULL. Como han señalado otros, es fácil derivar excepciones cuyo what() devuelve NULL, pero no estoy seguro de cómo encajan tales cosas en la conformidad de los estándares. Ciertamente, si está implementando what() en su propia clase de excepción, consideraría muy mala práctica permitir que devuelva NULL.

Más:

Por otra cuestión que se estudie si what() puede devolver NULL, y las cuestiones interesantes similares, vea Extending the C++ Standard Library by inheritance?

+0

Pero si overwridde qué y que es capturado por solo const std :: exception y luego puede ser NULL, por lo que probablemente sea mejor verificarlo ¿verdad? –

+0

Es virtual, así que es posible que los programadores malos lo hagan NULL – JaredPar

+0

Interesante. Ahora, dado que sé que a algunas personas les gusta implementar lo que a través de un std :: string y el método c_str() allí, tengo que preguntar: ¿puede c_str() una cadena std :: adecuadamente construida alguna vez devolver NULL? (Pregunto porque tengo esta situación en la base de código con la que trabajo y quiero saber si necesito agregar algunas TODO o no). –

2

Por supuesto que puede ser NULL:

class myexception: public exception 
{ 
    virtual const char* what() const throw() 
    { 
    return NULL; 
    } 
} myex; 
+1

Es posible hacer esto ** en el idioma ** (es decir su código se compilará), pero esto está prohibido por el estándar de C++ - vea la respuesta de Neil. IOW, no hagas esto, ya que el código de otras personas podría depender de que no lo hagas. –

+0

No creo que esté "fuera de la ley" - el estándar especifica el comportamiento de std :: exception :: que - no parece hacer ningún requisito de usuario derivado de std :: exception. –

5

Si alguien ha heredado de std :: exception y anulado qué devolver NULL, entonces esto es posible.

class CMyException : public std::exception 
    { 
    ... 
     virtual const char * what() const {return NULL;} 
    }; 

A pesar de encontrar excelente en el estándar de Neil, podría ser bueno comprobar si es NULO. Aunque las especificaciones de las clases secundarias de std :: exception indican que no deben devolver un valor NULL, nada en el compilador hará cumplir esto y el código anterior seguirá siendo legal según el idioma.

Esto puede ser una situación ideal para utilizar una aserción ...

assert(except.what() != NULL); 

o

if (except.what() != NULL) 
{ 
     ... normal processing ... 
} 
else 
{ 
     assert(false); 
} 

porque se trata de un caso en el que algo probablemente nunca llegase a ocurrir, y que está suponiendo que no debería suceder, pero aún me gustaría saber (en modo de depuración) cuando se demuestra que sus suposiciones son incorrectas. Entonces puede abordar su suposición incorrecta o abordar el código incorrecto que puede ir en contra de su suposición (asegúrese de que() no devuelva NULL).

+1

Es posible ** en el idioma ** (es decir, su código se compilará), pero esto está prohibido por el estándar de C++. Consulte la respuesta de Neil. –

+0

Sí, no estoy seguro de si no es un comportamiento indefinido si solo devuelve NULL. Está violando lo que especifica para qué(). –

0

Como muchos otros han señalado, what()no debería retorno a un puntero nulo pero podría. La sobrecarga de tiempo de ejecución de una prueba nula solo se produce en el caso excepcional donde, presumiblemente, es menos importante.

En cualquier caso, lo recomendaría al menos usando un assert.

Si el espacio del código también es una preocupación, con suerte el assert, sus pruebas, revisiones de código y otros QA estarán lo suficientemente completos para rastrear cualquier excepción ofensiva y no conforme antes de enviar.

Además, tenga cuidado con el código de control de excepciones que puede en sí mismo tirar (por ejemplo, como han dicho otros, la asignación de memoria con std::string al procesar una excepción std::bad_alloc.)

+0

La asignación de memoria no es una buena idea al procesar std :: bad_alloc. Para otras excepciones, no tiene sentido no usar std :: string. –

Cuestiones relacionadas