对于同一个程序:
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"
Run Code Online (Sandbox Code Playgroud)
在gcc5(链接):139639660962401
在gcc8(链接):1684234849
- 为什么值根据不同的编译器版本而有所不同?
行为未定义.
- 什么是编译器安全的方式从const char*移动到int64_t和向后
有点不清楚你的意思是"从const char*移动到int64_t".基于这个例子,我假设您的意思是创建一个从字符序列(长度不超过拟合)到64位整数的映射,其方式可以使用另一个进程转换回来 - 可能由另一个进程(版本的)编译编译器.
首先,创建一个int64_t对象,初始化为零:
int64_t i = 0;
Run Code Online (Sandbox Code Playgroud)
获取字符串的长度
auto len = strlen(s);
Run Code Online (Sandbox Code Playgroud)
检查它是否合适
assert(len < sizeof i);
Run Code Online (Sandbox Code Playgroud)
将字符序列的字节复制到整数上
memcpy(&i, s, len);
Run Code Online (Sandbox Code Playgroud)
(只要整数类型没有陷阱表示)行为定义良好,并且生成的整数在编译器版本中将是相同的,只要CPU字节顺序(和负数表示)保持不变即可.
读回字符串不需要复制,因为char特别允许别名所有其他类型:
auto back = reinterpret_cast<char*>(&i);
Run Code Online (Sandbox Code Playgroud)
请注意上一节中的资格.如果将整数(例如,通过网络)传递给在另一个CPU上运行的进程,则此方法不起作用.这也可以通过位移和屏蔽来实现,这样您就可以使用位移和屏蔽将八位字节复制到特定的重要位置.