C++ 重新解释的演员是如何工作的?

C++ 重新解释的演员是如何工作的?,c++,byte,binaryfiles,reinterpret-cast,C++,Byte,Binaryfiles,Reinterpret Cast,我想知道在幕后如何重新诠释演员阵容。我是从一本书上了解到这一点的,但我就是不明白。 例如,假设我有以下代码部分: int a = 255; char *pChar = reinterpret_cast<char*>(&a); 我想把变量a当作一系列字节char*: char *pChar = reinterpret_cast<char*>(&a); 它写入变量a的各个字节,对吗?它在运行时不执行任何操作: 与静态_cast不同,但与const_cast

我想知道在幕后如何重新诠释演员阵容。我是从一本书上了解到这一点的,但我就是不明白。 例如,假设我有以下代码部分:

int a = 255;
char *pChar = reinterpret_cast<char*>(&a);
我想把变量
a
当作一系列字节char*:

char *pChar = reinterpret_cast<char*>(&a);

它写入变量
a
的各个字节,对吗?

它在运行时不执行任何操作:

与静态_cast不同,但与const_cast一样,重新解释_cast 表达式不编译为任何CPU指令。这纯粹是一场战争 指示编译器处理序列的编译器指令 表达式的位(对象表示),就好像它具有 新型

这两种转换都非常危险,因为第一种转换将指针指向一个int,该int可能在内存中表示为
00ff
,因此不会打印任何内容,因为00='\0'是字符串char的结尾。这假设您在一台big-endian机器上。如果这是一个用非零值填充所有字节的
int
,您将无限期地读取该位置的末尾

第二个命令告诉编译器将
string
所在的位置视为
char*
,它不是实际字符串内容的起始地址,而是一个实现定义的结构,likley持有大小、容量和指针变量,或用于小字符串优化的字符串表示。由于大小和容量通常为64位宽,并且大小和容量可能都小于2^32,因此可能会遇到零字节,因此不会打印任何内容。再一次,如果没有意外的零字节,您的读取将无限期地结束

解决OP的编辑问题:

根据链接的cpp参考网站第5节

T1类型的任何指向对象的指针都可以转换为指向对象的指针 另一种类型的cv T2。这完全等同于static_cast(static_cast(expression))(这意味着如果T2 校准要求不比T1严格,即 指针不更改,并将结果指针转换回 转换为其原始类型将生成原始值)。无论如何 只有在系统允许的情况下,才能安全地取消引用结果指针 键入别名规则(请参见下文)

授予以下权利:

当指向动态类型为的对象的指针或引用 DynamicType是对指针或 引用其他类型的对象AliasedType时,强制转换始终 成功,但结果指针或引用只能用于 如果以下情况之一为真,则访问该对象:

AliasedType是char、unsigned char或std::byte:这允许 检查任何对象作为数组的对象表示 字节

,指针应指向
a
开始的地址

在这两个例子中,pChar将指出什么

它们将指向这些变量所在的内存的第一个字符

为什么我在打印内容时什么都看不到

你可能做得不对。您不能将它们打印为以null结尾的字符串(例如,
的内部表示包含0,它将被视为以null结尾的零)

您可以这样打印它们:

for (size_t i=0; i<sizeof(int); i++) {
    printf("%02x ", pChar[i]);
}
printf("\n");

<代码> >(SiZeTyt i=0;C++编译器和运行时库)将任何<代码> char */COD>作为C样式的空终止字节串。如果实际上不是,那么您不能打印(或以其他方式处理)。<代码> RealTytCaseCAST(/a)< /Cord>告诉编译器。“我们都知道
&a
不是
char*
,但让我们假设它是。"因为学习C++的代码> ReCytTyCase应该被避免。如果它是好的,学习它;然而,在代码中使用这个CAST的地方相对较少,而不会创建未定义的行为。@一些程序员UMM,WAT?!而C标准库的字符串函数通常会采用<代码> char *<代码>参数。它们应该包含一个
NUL
终止的字符串,该字符串不是
char*
类型本身固有的,编译器也不会做出这样的假设,除非在分析字符串文本时。SBO字符串可以将大小和/或容量字段作为字符串本身的一部分重新使用。但SBO字符串确实要存储它本身的某个地方是空的,所以这并不重要。另一方面,字符串可以实现为3个指针,而不是指针、大小和容量。是的,我把它保留为“可能”这是因为我不确定当前的实现是什么。我听说至少有一种可能的实现,它在24个字节的
size,pointer,cap
中存储多达23个字节,它重用了这样一个事实,即最后一个字节变为零,作为cap,也作为终止“\0”加倍。我认为在这种情况下,所有字节都可能是非零的特殊情况,因为第一个字节的一位用于区分小字符串与否,并且在
size==22
时,所有字节都应为非零。SBO必须具有空终止符,因为
c_str()
const
并返回一个以null结尾的字符串。这就留下了它不是SBO的情况。是的,因为在
最大大小-1
时,cap字节之前的字节仍然是零字节。我想这篇演讲详细阐述了这种优化:
char *pChar = reinterpret_cast<char*>(&a);
a_file.write(reinterpret_cast<char*>(&a), sizeof(a));
for (size_t i=0; i<sizeof(int); i++) {
    printf("%02x ", pChar[i]);
}
printf("\n");