简体   繁体   English

为什么我可以将 char* 隐式转换为 const char* 而不是 unsigned char*

[英]Why can I implicitly convert char* to const char* but not unsigned char*

The following code snippet produces a compile error:以下代码片段会产生编译错误:

char a = 'a';
const char* a_ = &a;
unsigned char b = 'b';
const char* b_ = &b;

The last line produces the error:最后一行产生错误:

error: invalid conversion from 'unsigned char*' to 'const char*'

I can implicitly convert from char* to const char* , but I cannot do the same for unsigned char* ?我可以从char*隐式转换为const char* ,但我不能对unsigned char*做同样的事情? What is the reason behind this?这背后的原因是什么?

You can add constness to the pointee.您可以向指针对象添加常量性。 That's permitted because it's useful and safe.这是允许的,因为它有用且安全。

But you can't just randomly change the pointee's type beyond that.但是你不能只是随机地改变指针的类型。

You're saying "I have a pointer to a char , hey, here it is, whoops no it's a unsigned char " and you cannot do that without a C-style "force" cast or a reinterpret_cast .你是说“我有一个指向char的指针,嘿,在这里,哎呀,它是一个unsigned char ”,如果没有 C 风格的“强制”强制转换或reinterpret_cast ,你就无法做到这一点。

This is the right code:这是正确的代码:

char a = 'a';
const char* a_ = &a;
unsigned char b = 'b';
const unsigned char* b_ = &b;   // (added "unsigned" here)

Because when you store a value to a signed char x;因为当你将一个值存储到一个有signed char x; and then fetch it through either signed char *xp = &x;然后通过有signed char *xp = &x;获取它(via *xp ) or a signed char const *xcp =&x; (通过*xp )或有signed char const *xcp =&x; , you get the same value. ,你得到相同的值。 Always.总是。

But if you have signed char x = -1;但是如果你已经signed char x = -1; and you fetch it through an unsigned char* pointer, you get a different value (255, barring exotic architectures).然后你通过一个unsigned char*指针获取它,你会得到一个不同的值(255,除非是异国架构)。

That's why INT *ip can be assigned to INT const * but not to UINT * (where INT and UINT is any signed integer type and its unsigned counterpart).这就是为什么可以将INT *ip分配给INT const *而不能分配给UINT * (其中INTUINT是任何有符号整数类型及其无符号对应物)。

The strict aliasing rules still allow you to access INT values via UINT pointers and vice-versa, but you need an explicit cast to obtain such a pointer (pointing to a differently signed version of the original type).严格的别名规则仍然允许您通过UINT指针访问INT值,反之亦然,但您需要显式转换才能获得这样的指针(指向原始类型的不同签名版本)。


Note: char has unspecified signedness.注意: char具有未指定的符号。 It's either like signed char or like unsigned char , but it is a type distinct from both of these (unlike every other integer type, where signed INT is the same as INT (except in bitfields)).它要么等signed char或类似的unsigned char ,但它是一种从两者的这些不同(不同于所有其他整数类型,其中signed INT是相同的INT (在位域除外))。

A pointer to a non-constant object can be implicitly converted to pointer to a constant object of the same type.指向非常量对象的指针可以隐式转换为指向相同类型的常量对象的指针。 So these declarations所以这些声明

char a = 'a';
const char* a_ = &a;

are valid.是有效的。

Now let's consider the following declarations (for clarity the qualifier const is removed)现在让我们考虑以下声明(为清楚起见,移除了限定符const

unsigned char b = 'b';
char* b_ = &b;

The expression in the right hand side has the type unsigned char * while the initialized object has the type char * .右侧的表达式具有unsigned char *类型,而初始化对象具有char *类型。 These two types are different and there is no implicit conversion from one type to another.这两种类型是不同的,并且没有从一种类型到另一种类型的隐式转换。 Instead you can write相反,你可以写

unsigned char b = 'b';
char* b_ = reinterpret_cast<char *>( &b );

In this case the both entities in the right hand side and in the left hand side have the same type.在这种情况下,右侧和左侧的两个实体具有相同的类型。 So you now can add the qualifier const for specification of the declared object因此,您现在可以为声明的对象的规范添加限定符 const

unsigned char b = 'b';
const char* b_ = reinterpret_cast<char *>( &b );

In C and C++ the types char , signed char and unsigned char are three different types.在 C 和 C++ 中, charsigned charunsigned char类型是三种不同的类型。 The type char can behave either as the type signed char or as the type unsigned char (can have the same range of values) but this does not make it signed or unsigned char.类型char可以表现为有signed char类型或unsigned char类型(可以具有相同的值范围),但这不会使其成为有符号或无符号字符。

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

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