Reinterpret casted value varies by compiler

  • A+
Category:Languages

For the same program:

const char* s = "abcd"; auto x1 = reinterpret_cast<const int64_t*>(s); auto x2 = reinterpret_cast<const char*>(x1); std::cout << *x1 << std::endl; std::cout << x2 << std::endl; // Always "abcd" 

In gcc5(link): 139639660962401
In gcc8(link): 1684234849

  1. Why does the value vary according to different compiler versions?
  2. What is then a compiler safe way to move from const char* to int64_t and backward(just like in this problem - not for actual integer strings but one with other chars as well)?

 


  1. Why does the value vary according to different compiler versions?

Behaviour is undefined.

  1. What is then a compiler safe way to move from const char* to int64_t and backward

It is somewhat unclear what you mean by "move from const char* to int64_t". Based on the example, I assume you mean to create a mapping from a character sequence (of no greater length than fits) into a 64 bit integer in a way that can be converted back using another process - possibly compiled by another (version of) compiler.

First, create a int64_tobject, initialise to zero:

int64_t i = 0; 

Get length of the string

auto len = strlen(s); 

Check that it fits

assert(len < sizeof i); 

Copy the bytes of the character sequence onto the integer

memcpy(&i, s, len); 

(As long as the integer type doesn't have trap representations) The behaviour is well defined, and the generated integer will be the same across compiler versions as long as the CPU endianness (and negative number representation) remains the same.

Reading the character string back doesn't require copying because char is exceptionally allowed to alias all other types:

auto back = reinterpret_cast<char*>(&i); 

Note the qualification in the last section. This method does not work if the integer is passed (across the network for example) to process running on another CPU. That can be achieved as well by bit shifting and masking so that you copy octets to certain position of significance using bit shifting and masking.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: