3

I have a byte array that represents double:

char number[8];

I need to cast this to actual double (which has 8 bytes as well). Based on advice I tried this, but it failed:

std::cout<<(*((*double)number))<<" is my number.\n";

Why did it fail and what should I do? I can, of course, extract the data using some << magic, but I don't want to do this - it would consume memory and make code too robust.

Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778
  • Type-punning like this is rather dangerous (though valid in the specific case of `char` IIRC, at least for now and as long as you only use one type). In general, a `union` is safer, and more convenient too. With pointers, strict aliasing is always out to get you. –  Mar 17 '13 at 18:25
  • @delnan, But reading from a member of a union that wasn't set last is UB, where as this is implementation-defined (at least the casting is IIRC). – chris Mar 17 '13 at 18:27
  • @chris You won't get anything better than implementation-defined, the standard doesn't even specify how many bits there are in a `char`. However, implementation-defined is much better than undefined behavior (which is what you get with stuff like `*(int*)&a_double` IIRC). More importantly, even if both are equally broken by the standard, many compilers perform type-based alias analysis which can break code doing type punning with pointers, but doesn't break type punning via unions IIUC. –  Mar 17 '13 at 18:30
  • I hate it when my code is too robust. Use `memcpy` to copy the bytes into a double, the compiler will make it just as fast. – Jonathan Wakely Mar 17 '13 at 22:12

3 Answers3

8

Why did it fail?

You have a typo here.

std::cout<<(*((*double)number))<<" is my number.\n";

It should be:

std::cout<<(*((double*)number))<<" is my number.\n";

and what should I do?

You could reduce the number of parenthesis used.

std::cout<< *(double*)number <<" is my number.\n";

You should use C++ casts instead of C casts, so it's clear what you're doing.

std::cout<< *reinterpret_cast<double*>(number) <<" is my number.\n";
Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
3

If you use c++, then use reinterpret_cast. C++ have much more expressive, as you see.

// cool c++
double value = *reinterpret_cast<double*>(number);

// c style
double value = (*((double*)number));
poitroae
  • 21,129
  • 10
  • 63
  • 81
1
char number[8];
double d;
// number is assumed to be filled with a buffer representing a double.
memcpy(&d, &number, sizeof(double));
std::cout << d;

Not sure if the sizeof is needed. The damage was already dealt when the assumption that a double is 8 bytes was made. I don't know what it says in the standard about doubles.

user123
  • 8,970
  • 2
  • 31
  • 52
  • 1
    The standard says that a double most be large enough to hold any `float` value, although I'm not sure what the exact wording used is. – Cubic Mar 17 '13 at 18:28