reinterpret_cast 是如何工作的?
How does the reinterpret_cast work?
我想知道 reinterpret_cast 在幕后是如何工作的。我正在从一本书中了解它,但我就是不明白。
例如。假设我有以下代码部分:
int a = 255;
char *pChar = reinterpret_cast<char*>(&a);
或
std::string str = "Hello";
char *pChar = reinterpret_cast<char*>(&str);
pChar 在这两个示例中指向什么,为什么我尝试打印它们的内容时看不到任何内容,当然还有 reinterpret_cast 是如何工作的?
编辑:
我知道 reinterpret_cast 使用起来很危险,只想用它从一块内存中将字节直接写入二进制文件。
我不明白的是,当我有一个
int a = 255; (00 00 00 FF in memory)
我想将变量 a
视为一系列字节,char* :
char *pChar = reinterpret_cast<char*>(&a);
pChar 会指向变量 a
(00 00 00 FF) 的各个字节吗?
所以当我想将 pChar
指向的二进制文件写入时:
a_file.write(reinterpret_cast<char*>(&a), sizeof(a));
它写入变量a
的各个字节,对吧?
它在 运行 时不执行任何操作。 Cpp reference:
Unlike static_cast, but like const_cast, the reinterpret_cast
expression does not compile to any CPU instructions. It is purely a
compiler directive which instructs the compiler to treat the sequence
of bits (object representation) of expression as if it had the type
new_type.
你的两个转换都非常危险,因为第一个指针指向一个 int,它可能在内存中表示为 00 00 00 FF
,因此不会打印任何东西,因为 00 == '\0',这是字符串结尾的字符。这假设您使用的是大端机器。如果这是用非零值填充所有字节的 int
,您将无限期读取该位置的末尾。
第二个告诉编译器将 string
所在的位置视为 char*
,这不是实际字符串内容的起始地址,而是一个实现定义的结构,这很可能保存大小、容量和指针变量或用于小字符串优化的字符串表示。由于大小和容量通常为 64 位宽,并且大小和容量可能都小于 2^32,因此您可能 运行 为零字节,因此不打印任何内容。再一次,如果没有意外的零字节,你的读取将无限期地结束。
要解决 OP 的编辑问题:
根据链接的 cpp 参考站点的第 5 节
Any pointer to object of type T1 can be converted to pointer to object
of another type cv T2. This is exactly equivalent to static_cast(static_cast(expression)) (which implies that if T2's
alignment requirement is not stricter than T1's, the value of the
pointer does not change and conversion of the resulting pointer back
to its original type yields the original value). In any case, the
resulting pointer may only be dereferenced safely if allowed by the
type aliasing rules (see below)
授予以下:
When a pointer or reference to object whose dynamic type is
DynamicType is reinterpret_cast (or C-style cast) to a pointer or
reference to object of a different type AliasedType, the cast always
succeeds, but the resulting pointer or reference may only be used to
access the object if one of the following is true: ...
AliasedType is char, unsigned char, or std::byte: this permits
examination of the object representation of any object as an array of
bytes. ...
,指针应该指向a
开始的地址。
What will pChar pointed to in both examples?
它们将指向这些变量所在内存的第一个字符。
why i can't see anything when i try to print their contents
你可能做错了。您不能将它们打印为空终止字符串(例如,a
的内部表示包含 0,它将被视为终止零)。
你可以这样打印它们:
for (size_t i=0; i<sizeof(int); i++) {
printf("%02x ", pChar[i]);
}
printf("\n");
这将以十六进制打印 a
的字符值。这样,您将看到 ff 00 00 00
(假设您使用的是小端计算机)。
您可以对 std::string
执行相同的操作。您将看到 std::string
.
的内存表示
(您可以使用“%c”将内容打印为字符。如果将标准输出重定向到文件,您将在文件中看到变量的内部表示。
and of course how does reinterpret_cast work?
它只是重新解释它的参数,假装它有另一种类型。不涉及运行时成本(注意:此解释已高度简化)。
Will pChar point to the individual bytes of variable a (00 00 00 FF)?
是的,假设 char 是一个字节,并且您使用的是大端计算机。
It writes the individual bytes of variable a, right
是的,但大概你也可以在没有任何 reinterpret_cast 的情况下做同样的事情,这里不需要它(假设 a_file.write
的第一个参数是 void *
)
我想知道 reinterpret_cast 在幕后是如何工作的。我正在从一本书中了解它,但我就是不明白。 例如。假设我有以下代码部分:
int a = 255;
char *pChar = reinterpret_cast<char*>(&a);
或
std::string str = "Hello";
char *pChar = reinterpret_cast<char*>(&str);
pChar 在这两个示例中指向什么,为什么我尝试打印它们的内容时看不到任何内容,当然还有 reinterpret_cast 是如何工作的?
编辑: 我知道 reinterpret_cast 使用起来很危险,只想用它从一块内存中将字节直接写入二进制文件。 我不明白的是,当我有一个
int a = 255; (00 00 00 FF in memory)
我想将变量 a
视为一系列字节,char* :
char *pChar = reinterpret_cast<char*>(&a);
pChar 会指向变量 a
(00 00 00 FF) 的各个字节吗?
所以当我想将 pChar
指向的二进制文件写入时:
a_file.write(reinterpret_cast<char*>(&a), sizeof(a));
它写入变量a
的各个字节,对吧?
它在 运行 时不执行任何操作。 Cpp reference:
Unlike static_cast, but like const_cast, the reinterpret_cast expression does not compile to any CPU instructions. It is purely a compiler directive which instructs the compiler to treat the sequence of bits (object representation) of expression as if it had the type new_type.
你的两个转换都非常危险,因为第一个指针指向一个 int,它可能在内存中表示为 00 00 00 FF
,因此不会打印任何东西,因为 00 == '\0',这是字符串结尾的字符。这假设您使用的是大端机器。如果这是用非零值填充所有字节的 int
,您将无限期读取该位置的末尾。
第二个告诉编译器将 string
所在的位置视为 char*
,这不是实际字符串内容的起始地址,而是一个实现定义的结构,这很可能保存大小、容量和指针变量或用于小字符串优化的字符串表示。由于大小和容量通常为 64 位宽,并且大小和容量可能都小于 2^32,因此您可能 运行 为零字节,因此不打印任何内容。再一次,如果没有意外的零字节,你的读取将无限期地结束。
要解决 OP 的编辑问题:
根据链接的 cpp 参考站点的第 5 节
Any pointer to object of type T1 can be converted to pointer to object of another type cv T2. This is exactly equivalent to static_cast(static_cast(expression)) (which implies that if T2's alignment requirement is not stricter than T1's, the value of the pointer does not change and conversion of the resulting pointer back to its original type yields the original value). In any case, the resulting pointer may only be dereferenced safely if allowed by the type aliasing rules (see below)
授予以下:
When a pointer or reference to object whose dynamic type is DynamicType is reinterpret_cast (or C-style cast) to a pointer or reference to object of a different type AliasedType, the cast always succeeds, but the resulting pointer or reference may only be used to access the object if one of the following is true: ...
AliasedType is char, unsigned char, or std::byte: this permits examination of the object representation of any object as an array of bytes. ...
,指针应该指向a
开始的地址。
What will pChar pointed to in both examples?
它们将指向这些变量所在内存的第一个字符。
why i can't see anything when i try to print their contents
你可能做错了。您不能将它们打印为空终止字符串(例如,a
的内部表示包含 0,它将被视为终止零)。
你可以这样打印它们:
for (size_t i=0; i<sizeof(int); i++) {
printf("%02x ", pChar[i]);
}
printf("\n");
这将以十六进制打印 a
的字符值。这样,您将看到 ff 00 00 00
(假设您使用的是小端计算机)。
您可以对 std::string
执行相同的操作。您将看到 std::string
.
(您可以使用“%c”将内容打印为字符。如果将标准输出重定向到文件,您将在文件中看到变量的内部表示。
and of course how does reinterpret_cast work?
它只是重新解释它的参数,假装它有另一种类型。不涉及运行时成本(注意:此解释已高度简化)。
Will pChar point to the individual bytes of variable a (00 00 00 FF)?
是的,假设 char 是一个字节,并且您使用的是大端计算机。
It writes the individual bytes of variable a, right
是的,但大概你也可以在没有任何 reinterpret_cast 的情况下做同样的事情,这里不需要它(假设 a_file.write
的第一个参数是 void *
)