繁体   English   中英

为什么将unsigned char *转换为char *需要reinterpret_cast?

[英]Why does casting unsigned char* to char* require reinterpret_cast?

stackoverflow上有很多关于读取和写入unsigned char的帖子。 这些帖子建议使用reinterpret_castunsigned char*char * 我想知道为什么需要它,因为两种类型都有相同的大小。

我在Windows和Linux上运行代码,它工作正常(有或没有重新解释转换)。 我错过了什么吗? 如果没有reinterpret_cast ,有人可以发布一个无效的代码吗? 注意,我说的是unsigned char (不是unsigned int )。

#include <iostream>
#include <fstream>

std::ofstream os;
unsigned char *buff = new unsigned char[3]{ 0xe4, 0xe1, 0xd4 };
os.open("image.jpg", std::ios::out | std::ios::binary);

os.write(reinterpret_cast<char*>(buff), 3 * sizeof(unsigned char));
// or: os.write((char*)(buff), 3 * sizeof(unsigned char));
os.close();

std::ifstream file;
memset(buff, 0, 3 * sizeof(unsigned char));

file.open("image.jpg", std::ios::in | std::ios::binary);
file.read(reinterpret_cast<char*>(buff), 3 * sizeof(unsigned char));
//or: file.read((char *)buff, 3 * sizeof(unsigned char));
file.close();

reinterpret_cast从不“需要”; 任何reinterpret_cast可以做的事情都可以通过C风格演员同样完成。

存在特殊的强制转换语法,因为需要reinterpret_cast东西往往是危险的东西,因此可能应该注意代码中的那些点。 reinterpret_cast还可以防止意外删除const ,C样式的强制转换允许你这样做。

为什么将unsigned char *转换为char *需要reinterpret_cast?

C ++是一种打字语言。 尽管有不同的大小, unsigned charchar是不同的类型。 指向unsigned char和指针char也是不同的类型。

C ++语言具有类型安全性。 类型系统旨在通过禁止使用一个对象来防止您犯错,就像它是另一个不相关的类型一样。 存在从某些类型到其他类型的隐式转换,这允许从另一类型的对象创建一种类型的新对象1 此外,还有明确的转换,当没有隐式转换时,它们允许相同的转换。 其中一个显式转换允许完全绕过类型系统:重新解释转换。

1同样,您可以将引用转换为其他类型的新引用。

charunsigned char无关。 指向一个指针不能隐式转换为指向另一个指针。 当参数具有另一种类型时,传递一个作为参数是不正确的。 如果您明确告诉编译器忽略类型系统,那么它将无法保护您免受使用错误类型的潜在错误。 在这种情况下,重新解释是有意的,并且(据我所知)并非错误。 正是这些有意的重新解释是重新解释铸造存在的原因。

我想知道为什么需要它,因为两种类型都有相同的大小。

类型的含义并不完全用类型的大小来描述。


请注意,重新解释转换是不安全的。 处理重新解释的指针/引用时必须遵循许多规则,违反任何规则将导致未定义的行为。 只是因为它在这里可能是正确的,不要假设每次遇到与类型不匹配时都可以使用重新解释。

2另请注意,如果不存在符合类型系统的转换,则C样式转换(char*)buff将重新解释转换。 它也会进行const转换,重新解释转换不行。 这使得C风格的演员阵容更加不安全。 通常建议明确使用您打算使用的强制转换类型(静态,重新解释或常量转换)而不是C样式强制转换,它执行一个或多个组合,具体取决于哪个恰好适合。

如果没有reinterpret_cast,有人可以发布一个无效的代码吗?

如果从程序中删除reinterpret_cast ,那么它将是格式错误的。 该标准并不保证它会起作用。 如果使用不扩展语言的编译器,它可能不起作用。 例如, GCC拒绝编译

当然,任何需要reinterpret_cast程序都可以重写,以便在其位置使用C样式,因为2


PS通常情况下,更好的设计可以避免演员阵容。 在这种情况下,您可以使用std::basic_ofstream<unsigned char>std::basic_ifstream<unsigned char> ,并且不需要强制转换。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM