Usted ha hecho esto:
union NumericType Values = { 10 }; // iValue = 10
printf("%d\n", Values.iValue);
Values.dValue = 3.1416;
Cómo un compilador utiliza la memoria de esta unión es similar al uso de la variable con mayor tamaño y la alineación (cualquiera de ellos si hay varios), y volver a interpretar al elenco uno de los otros tipos en la unión está escrito/visitada, como en:
double dValue; // creates a variable with alignment & space
// as per "union Numerictype Values"
*reinterpret_cast<int*>(&dValue) = 10; // separate step equiv. to = { 10 }
printf("%d\n", *reinterpret_cast<int*>(dValue)); // print as int
dValue = 3.1416; // assign as double
printf("%d\n", *reinterpret_cast<int*>(dValue)); // now print as int
el problema es que en el establecimiento de dValue a 3.1416 que ha sobrescrito por completo los bits que utilizan para mantener el número 10. el nuevo valor puede parecer basura, pero es simplemente el resultado de interpretar t El primero (tamaño de int) bytes del doble 3.1416, confiando en que allí haya un valor int útil.
Si desea que las dos cosas sean independientes, configurar el doble no afecta a la int almacenada anteriormente, entonces debe usar un struct
/class
.
Puede ayudarle a considerar este programa:
#include <iostream>
void print_bits(std::ostream& os, const void* pv, size_t n)
{
for (int i = 0; i < n; ++i)
{
uint8_t byte = static_cast<const uint8_t*>(pv)[i];
for (int j = 0; j < 8; ++j)
os << ((byte & (128 >> j)) ? '1' : '0');
os << ' ';
}
}
union X
{
int i;
double d;
};
int main()
{
X x = { 10 };
print_bits(std::cout, &x, sizeof x);
std::cout << '\n';
x.d = 3.1416;
print_bits(std::cout, &x, sizeof x);
std::cout << '\n';
}
Lo cual, para mí, produce esta salida:
00001010 00000000 00000000 00000000 00000000 00000000 00000000 00000000
10100111 11101000 01001000 00101110 11111111 00100001 00001001 01000000
Fundamentalmente, la primera mitad de cada línea se muestran los 32 bits que están utilizado para iValue: tenga en cuenta que el binario 1010 en el byte menos significativo (a la izquierda en una CPU Intel como la mía) es 10 decimal. Escribir 3.1416 cambia los 64 bits completos a un patrón que representa 3.1416 (ver http://en.wikipedia.org/wiki/Double_precision_floating-point_format). El viejo patrón 1010 se sobrescribe, golpeado, una memoria electromagnética no más.
¿es un problema de conversión endian? ~ Definir "basura". Eso realmente nos ayudaría a responder su pregunta. – jcolebrand
@drachenstern: su pregunta se ve perfectamente formulada y en forma ... mucho mejor que la habitual "muéstrame el código" que obtenemos de los recién llegados. – mpen
@Mark ~ Estoy de acuerdo. Pero dado que es nuevo, podría ser bueno tener una referencia del sitio. Además, necesitamos saber qué define como "basura" y eso hubiera sido una buena inclusión. Al menos no lo vinculé directamente con el artículo de JonSkeet;) ... Lo he estado haciendo por muchos recién llegados como un poco de limpieza. Bienvenido al club, sé un buen miembro de la comunidad, ese tipo de cosas. No fue una publicación perjudicial. – jcolebrand