“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 deFoo
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
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íneaconstexpr const int Foo::OUT_OF_BOUNDS;
fuera deFoo
, pero aun así VS2015 da la advertencia. Quitarconstexpr
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 referenciaconst int&
a una variable local o temporal, lo cual no está permitido. Sin embargo, la variableOUT_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 comoconstexpr
para asegurar que tenga un valor constante y una dirección. Alternativamente, se puede quitarconstexpr
, dividir la declaración de la definición y definir la variable fuera de la clase para evitar la advertencia.