为什么我不能在 char * 和 unsigned char * 之间进行静态转换?

显然编译器认为它们是不相关的类型,因此需要 reinterpret_cast.为什么会有这样的规定?

Apparently the compiler considers them to be unrelated types and hence reinterpret_cast is required. Why is this the rule?

推荐答案

它们是完全不同的类型,见标准:

They are completely different types see standard:

3.9.1 基本类型 [basic.fundamental]

3.9.1 Fundamental types [basic.fundamental]

1 声明为字符 char) 的对象应足够大存储实现的基本字符集的任何成员.如果一个该集合中的字符存储在字符对象中,积分该字符对象的值等于单个的值该字符的字符文字形式.它是实现定义的 char 对象是否可以持有负数价值观.字符可以显式声明为无符号或
签.普通字符、有符号字符和无符号字符是三种不同的类型. char、signed char 和 unsigned char占用相同的存储量并具有相同的对齐方式要求(basic.types);也就是说,它们具有相同的对象表示.对于字符类型,对象的所有位
表征参与价值表征.对于未签名字符类型,值表示的所有可能的位模式代表数字.这些要求不适用于其他类型.在任何特定的实现,一个普通的 char 对象都可以采用与有符号字符或无符号字符相同的值;哪一个是实现定义.

1 Objects declared as characters char) shall be large enough to store any member of the implementation's basic character set. If a character from this set is stored in a character object, the integral value of that character object is equal to the value of the single character literal form of that character. It is implementation-defined whether a char object can hold negative values. Characters can be explicitly declared unsigned or
signed. Plain char, signed char, and unsigned char are three distinct types. A char, a signed char, and an unsigned char occupy the same amount of storage and have the same alignment requirements (basic.types); that is, they have the same object representation. For character types, all bits of the object
representation participate in the value representation. For unsigned character types, all possible bit patterns of the value representation represent numbers. These requirements do not hold for other types. In any particular implementation, a plain char object can take on either the same values as a signed char or an unsigned char; which one is implementation-defined.

与此类似也是以下失败的原因:

So analogous to this is also why the following fails:

unsigned int* a = new unsigned int(10);
int* b = static_cast<int*>(a); // error different types

ab 是完全不同的类型,你真正要问的是为什么 static_cast 可以毫无问题地执行以下操作时限制如此之大

a and b are completely different types, really what you are questioning is why is static_cast so restrictive when it can perform the following without problem

unsigned int a = new unsigned int(10);
int b = static_cast<int>(a); // OK but may result in loss of precision

为什么不能推断出目标类型是相同的位域宽度并且可以表示?它可以对标量类型执行此操作,但对于指针,除非目标是从源派生的,并且您希望执行向下转换,然后在指针之间进行强制转换是行不通的.

and why can it not deduce that the target types are the same bit-field width and can be represented? It can do this for scalar types but for pointers, unless the target is derived from the source and you wish to perform a downcast then casting between pointers is not going to work.

Bjarne Stroustrop 说明了为什么 static_cast 在此链接中很有用:http://www.stroustrup.com/bs_faq2.html#static-cast 但以缩写形式让用户清楚地说明他们的意图是什么,并让编译器有机会检查你打算可以实现,因为 static_cast 不支持不同指针类型之间的转换,那么编译器可以捕捉到这个错误来提醒用户,如果他们真的想要做这个转换,那么他们应该使用 reinterpret_cast.

Bjarne Stroustrop states why static_cast's are useful in this link: http://www.stroustrup.com/bs_faq2.html#static-cast but in abbreviated form it is for the user to state clearly what their intentions are and to give the compiler the opportunity to check that what you are intending can be achieved, since static_cast does not support casting between different pointer types then the compiler can catch this error to alert the user and if they really want to do this conversion they then should use reinterpret_cast.

相关文章