es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

“advertencia C4172: devolviendo la dirección de una variable local o temporal” al devolver una referencia a un miembro estático.

Tengo esta clase con una función que devuelve un valor. Por razones complicadas, el valor debe ser devuelto como una referencia const.

(Ejemplo mínimo de trabajo contiene una matriz de int, el código real tiene objetos más complejos, de ahí la referencia)

class Foo
{
public:
    static constexpr const int VALOR_FUERA_DE_RANGO = -9999;
    const int& ret(int i) const { return i < 0 || i > 4 ? VALOR_FUERA_DE_RANGO : test[i]; }

private:
    int test[5] = {0, 1, 2, 3, 4};
};

Esto me da el aviso warning C4172: returning address of local variable or temporary en VS2015 y ni siquiera compila con GCC.

  • Agregar la línea constexpr const int Foo::VALOR_FUERA_DE_RANGO; fuera de Foo permite que GCC compile sin problemas. VS2015 sigue dando el aviso.
  • Eliminar constexpr y separar la declaración de la definición soluciona el aviso, pero ¿por qué debería tener que hacer eso?

¿VALOR_FUERA_DE_RANGO no es local y no es temporal, ¿verdad? ¿No tiene una dirección cuando se define y declara dentro de la definición de la clase?

Ver el aviso en vivo: https://godbolt.org/z/fv397b9rr

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Como experto en IT especializado en c++, c++11, static y constexpr, el valor de retorno de referencia const de la función en el código proporcionado genera una advertencia en VS2015 y no se compila con GCC porque trata de devolver una variable local o temporal. Para solucionar la advertencia, se puede agregar la línea constexpr const int Foo::OUT_OF_BOUNDS; fuera de Foo, pero aun así VS2015 da la advertencia. Quitar constexpr y dividir la declaración de la definición también puede solucionar la advertencia, pero esto no debería ser necesario.

    La razón de la advertencia es que la función ret() devuelve una referencia const int& a una variable local o temporal, lo cual no está permitido. Sin embargo, la variable OUT_OF_BOUNDS no es local ni temporal, por lo que no debería generar una advertencia. Tiene una dirección cuando se define y declara dentro de la definición de la clase, pero el compilador aún puede interpretarla como una variable local o temporal.

    Para resolver el problema, se puede declarar OUT_OF_BOUNDS fuera de la definición de la clase y marcarla como constexpr para asegurar que tenga un valor constante y una dirección. Alternativamente, se puede quitar constexpr, dividir la declaración de la definición y definir la variable fuera de la clase para evitar la advertencia.

Comments are closed.