Evitar inadecuada inicialización std :: string con NULL const char * usando g ++

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

  •  18-09-2019
  •  | 
  •  

Pregunta

Hay alguna g opciones A ++ que pueden detectar la inicialización indebido de std :: string con carbón NULL const *?

Yo estaba en el proceso de convertir algunos campos en los int std :: string, es decir:

struct Foo
{
   int id;
   Foo() : id(0) {} 
};

... convertido en:

struct Foo
{
   std::string id;
   Foo() : id(0) {} //oooops!
};

Me daba completamente mala inicialización 'id' con 0 y g ++ me dio ninguna advertencia en absoluto. Se ha detectado este error en el tiempo de ejecución (constructor de std :: string inició una excepción), pero realmente me gustaría para detectar tales cosas en el tiempo de compilación. ¿Hay alguna forma?

¿Fue útil?

Solución

Creo que es en realidad un comportamiento indefinido y no se comprueba por el compilador. Tienes suerte de que esta implementación se produce una excepción.

Sin embargo, puede evitar este tipo de problemas especificando que desea defecto o cero-inicialización de una manera independiente del tipo:

struct Foo
{
   X id;
   Foo() : id() {} //note empty parenthesis
};

Otros consejos

No puedo pensar en una manera de detectar esto en tiempo de compilación, así que escribió una función de generador de cadenas que adecuadamente se ocupa de punteros nulos:

//  FUNCTION :      safe_string(char const* pszS)
//  PARAMATERS :    pszS        source string to build a string from (may be NULL or 0-length)
//  DESCRIPTION :   Safely builds a string object from a char*, even a NULL pointer
//  RETURNS :       string

template<class C>
inline basic_string<C> safe_string(const C* input)
{
    if( !input )
        return basic_string<C>();
    return basic_string<C>(input);
}

Yo uso esto cada vez se crea una cadena y existe la posibilidad de la entrada puede ser NULL.

Existe la infraestructura en GCC para producir exactamente este tipo de advertencia siguiente:

void foo(const char* cstr) __attribute__((nonnull (1)));

void bar() {
    foo(0);
}

cuando se compila con -Wnonnull (que está implicado por -Wall) produce:

warning: null argument where non-null required (argument 1)

Así que, en principio, usted debería ser capaz de modificar el sistema de cabecera relevante (o, mejor para experimentar, modificar su propio $ HOME / bits / copiar basic_string.h y luego anular el sistema uno con -isystem $HOME) de manera similar:

basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
    __attribute__((nonnull (1)));

Sin embargo, esto no ayuda, porque (al menos en 4.0.1) -Wnonnull no es compatible en C ++ y el atributo es aparentemente ignorada. No es obvio por qué esto es así; tal vez se consideró que interactuaba con la sobrecarga mal o algo así.

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