c++ - const_cast - static cast
¿Cómo maneja C++ un doble const y que se refiere a un int? (4)
Estaba trabajando en un código de plantilla esta mañana, donde usé un BOOST_STATIC_ASSERT
para asegurarme de que no estaba creando una referencia al tipo incorrecto, ya que pensé que podría ser un mensaje de error más claro. Sin embargo, cuando intenté eliminar la aserción estática para echar un vistazo al error del compilador alternativo, me sorprendió descubrir que gcc ni siquiera se queja cuando intenta hacer un doble constante y referirme a un int:
#include <iostream>
int main()
{
int x = 5;
const double& y = x;
std::cout << y << std::endl;
return 0;
}
Compila, y ni siquiera avisa:
$ g++ ~/stuff/badRef.cpp -Wall -Wextra -pedantic
$ a.out
5
¿Que está pasando aqui? ¿Es este comportamiento indefinido? Si es así, ¿por qué gcc no se queja? En mi máquina, int es de 4 bytes y un doble es 8. Eso significa que cuando se imprime un doble y debería interpretar 8 bytes en esa dirección como doble e imprimirlo, sin embargo, en realidad hay un int de 4 bytes en esa ubicación.
Muy confundido. ¡Ayuda!
Está bien definido y es legal. y
refiere a un temporal. Considera también cuando pases parámetros:
void foo(const int& p);
foo(3.14);
Tenga en cuenta también que esto no es válido en C ++ si la referencia no es constante . VS 6 se equivocó y permitió vincular una referencia mutable a una temporal. Esto se aplica sólo a las referencias const.
Este es un buen ejemplo para aquellos que piensan que los punteros y las referencias son iguales.
double const*const y2 = &x;
gives
bad.cpp:7:30: error: cannot convert ‘int*’ to ‘const double* const’ in initialization
La razón por la que funciona para las referencias se explica en las otras publicaciones.
const T&
puede vincularse a un temporal, por lo que x
se convierte a double
y la copia se liga a y
. Si marca, verá que &x != &y
La razón de este comportamiento es permitir que los literales pasen a las funciones que toman sus parámetros por referencia const
.
const double& y = x;
crea un double
temporal con el valor static_cast<double>(x)
, luego enlaza ese temporal a y
. La vida útil del temporal se extiende para que coincida con la vida útil de y
.
Esto es completamente legal C ++ (03 y 11), de ahí la falta de advertencia / error.