3

I am a little confused on how casts work in C++.
I have a 4 bytes integer which I need to convert to a char[32] and then convert it back in some other function.

I am doing the following :

uint32_t v = 100;
char ch[32]; // This is 32 bytes reserved memory
memcpy(ch,&v,4);
uint32_t w = *(reinterpret_cast<int*>(ch)); // w should be equal to v 

I am getting the correct results on my compiler, but I want to make sure if this is a correct way to do it.

Rajesh
  • 33
  • 4
  • Possible duplicate of [Simple int to char\[\] conversion](https://stackoverflow.com/questions/5050067/simple-int-to-char-conversion) – Smit Ycyken Mar 08 '18 at 17:35
  • Why are you using a 32 byte char array to store an integer? – Héctor C. Mar 08 '18 at 17:36
  • just note about reinterpret_cast; reinterpret_cast is for converting between pointer types, you're using it to convert from char array to int pointer and dereferencing it to take its value, it's redundant – Onur A. Mar 08 '18 at 17:37
  • I think the last cast from `char[]` to `int*` breaks strict aliasing rules. If you want to convert back to `int` you should use another `memcpy`. Also `int` isn't guaranteed to be 32 bits wide. – Miles Budnek Mar 08 '18 at 17:40
  • It's a 32-**bit** integer = 4 bytes. – super Mar 08 '18 at 17:51
  • @super, yes my bad, edited it. Basically I have a fixed buffer in which I can put any data I want. (can be integer or string). Then I interpret the data in the buffer in some other function. I don't want the overhead of converting the int to char, so I wanted to somehow interpret the buffer as an integer. – Rajesh Mar 08 '18 at 17:55
  • @Rajesh This also means that you can use `char ch[4]`. – super Mar 08 '18 at 17:57
  • @SmitYcyken: That is something else. – Lightness Races in Orbit Mar 08 '18 at 17:59
  • @super shouldn't that ideally be `char ch[sizeof(int)]`, just to be sure? – UnholySheep Mar 08 '18 at 18:00
  • @OnurA.: I think it's fairly clear that the example is contrived for the purposes of exposition. Wanting to serialise an integer to a sequence of bytes, and back again, is not unusual. – Lightness Races in Orbit Mar 08 '18 at 18:24
  • @LightnessRacesinOrbit surely it's not unusual. The unusual thing is using using reinterpret_cast for this purposes, since atoi() and stoi() already exists for this purpose – Onur A. Mar 08 '18 at 18:31
  • @OnurA.: No, again, those do completely different things. It is a different purpose. – Lightness Races in Orbit Mar 08 '18 at 18:32
  • @LightnessRacesinOrbit fair enough! +1 for your answer also. – Onur A. Mar 08 '18 at 18:36
  • @LightnessRacesinOrbit cheers! – Onur A. Mar 08 '18 at 18:39
  • Talking about storing integers as char arrays. This frequently happen to me when I need to store a few integers (sometimes uint8_t, small ones) as a char array. And write to disk. Later read them back. It is quite tricky, have to be very careful about signed integer. – Kemin Zhou Apr 04 '22 at 23:04

1 Answers1

4

Technically, no. You are at risk of falling foul of your CPU's alignment rules, if it has any.

You may alias an object byte-by-byte using char*, but you can't take an actual char array (no matter where its values came from) and pretend it's some other object.

You will see that reinterpret_cast<int*> method a lot, and on many systems it will appear to work. However, the "proper" method (if you really need to do this at all) is:

const auto INT_SIZE = sizeof(int);
char ch[INT_SIZE] = {};

// Convert to char array
const int x = 100;
std::copy(
   reinterpret_cast<const char*>(&x),
   reinterpret_cast<const char*>(&x) + INT_SIZE,
   &ch[0]
);

// Convert back again
int y = 0;
std::copy(
   &ch[0],
   &ch[0] + INT_SIZE,
   reinterpret_cast<char*>(&y)
);

(live demo)

Notice that I only ever pretend an int is a bunch of chars, never the other way around.

Notice also that I have also swapped your memcpy for type-safe std::copy (although since we're nuking the types anyway, that's sort of by-the-by).

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • "You are at risk of falling foul of your CPU's alignment rules". Is it possible to clarify this part, is it because of endianness ? – rafoo Dec 05 '21 at 04:27
  • No, @rafoo; alignment is something different from endianness. See, e.g., https://stackoverflow.com/questions/381244/purpose-of-memory-alignment – Cody Gray - on strike Apr 16 '22 at 15:11