C++ 从 unsigned char* 到 char* 的无效转换

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15046162/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 18:56:10  来源:igfitidea点击:

Invalid conversion from unsigned char* to char*

c++charsignedunsigned-char

提问by nightlytrails

Here is a code -

这是一个代码 -

  1 int main(int argc, char *argv[])
  2 {
  3     signed char S, *psc;
  4     unsigned char U,  *pusc;
  5     char C, *pc;
  6 
  7     C = S;
  8     C = U;
  9 
 10     pc = psc;
 11     pc = pusc;
 12 
 13     return 0;
 14 }

$ gcc test.cpp -o a
test.cpp: In function ‘int main(int, char**)':
test.cpp:10:7: error: invalid conversion from ‘signed char*' to ‘char*' [-fpermissive]
test.cpp:11:7: error: invalid conversion from ‘unsigned char*' to ‘char*' [-fpermissive]

This is compiled on gcc version 4.6.3 on Ubuntu 12.10 on an Intel 32-bit machine.

这是在英特尔 32 位机器上的 Ubuntu 12.10 上的 gcc 4.6.3 版上编译的。

Considering that chartype is unsigned charon x86.-

考虑到该char类型unsigned char在 x86 上。——

If assignments on line 7 and 8 for non-pointer types are Ok, why errors are thrown for pointer types on lines 10 and 11 ?

如果第 7 行和第 8 行对非指针类型的赋值没问题,为什么第 10 行和第 11 行的指针类型会抛出错误?

Also, should C = Usucceeds without requiring a cast?

另外,应该C = U在不需要演员的情况下成功吗?

回答by Andy Prowl

First of all, it is important to stress the fact that char, signed char, and unsigned charare all different types. Section 4.10 of the C++11 Standard defines the three possible standard pointer conversions between pointers of different types:

首先,要强调的事实,这是非常重要的charsigned charunsigned char都是不同的类型。C++11 标准的 4.10 节定义了不同类型指针之间的三种可能的标准指针转换:

1 . A null pointer constant is an integral constant expression (5.19) prvalue of integer type that evaluates to zero or a prvalue of type std::nullptr_t. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of object pointer or function pointer type. Such a conversion is called a null pointer conversion. Two null pointer values of the same type shall compare equal. The conversion of a null pointer constant to a pointer to cv-qualified type is a single conversion, and not the sequence of a pointer conversion followed by a qualification conversion (4.4). A null pointer constant of integral type can be converted to a prvalue of type std::nullptr_t. [ Note: The resulting prvalue is not a null pointer value. —end note ]

1 . 空指针常量是计算结果为零的整数类型的整数常量表达式 (5.19) 纯右值或 std::nullptr_t 类型的纯右值。空指针常量可以转换为指针类型;结果是该类型的空指针值,并且与对象指针或函数指针类型的所有其他值区分开来。这种转换称为空指针转换。相同类型的两个空指针值比较相等。将空指针常量转换为指向 cv 限定类型的指针是一次转换,而不是指针转换后跟限定转换 (4.4) 的序列。整数类型的空指针常量可以转换为 std::nullptr_t 类型的纯右值。[ 注意:生成的纯右值不是空指针值。——尾注]

This is not relevant, since we don't have null pointers of type nulltptr_there.

这无关紧要,因为我们nulltptr_t这里没有空指针类型。

2 . A prvalue of type “pointer to cv T,” where T is an object type, can be converted to a prvalue of type “pointer to cv void”. The result of converting a “pointer to cv T” to a “pointer to cv void” points to the start of the storage location where the object of type T resides, as if the object is a most derived object (1.8) of type T (that is, not a base class subobject). The null pointer value is converted to the null pointer value of the destination type.

2 . 类型为“指向 cv T 的指针”的纯右值(其中 T 是对象类型)可以转换为类型为“指向 cv void 的指针”的纯右值。将“指向 cv T 的指针”转换为“指向 cv void 的指针”的结果指向类型 T 的对象所在的存储位置的开头,就好像该对象是类型 T 的最派生对象 (1.8) (即,不是基类子对象)。空指针值转换为目标类型的空指针值。

This cannot apply, since the destination type is not void. Finally,

这不适用,因为目标类型不是void。最后,

3 . A prvalue of type “pointer to cv D”, where D is a class type, can be converted to a prvalue of type “pointer to cv B”, where B is a base class (Clause 10) of D. If B is an inaccessible (Clause 11) or ambiguous (10.2) base class of D, a program that necessitates this conversion is ill-formed. The result of the conversion is a pointer to the base class subobject of the derived class object. The null pointer value is converted to the null pointer value of the destination type.

3 . 类型为“指向 cv D 的指针”的纯右值,其中 D 是类类型,可以转换为类型为“指向 cv B 的指针”的纯右值,其中 B 是 D 的基类(第 10 条)。如果 B 是一个无法访问(第 11 条)或不明确(10.2)的 D 基类,需要这种转换的程序是格式错误的。转换的结果是一个指向派生类对象的基类子对象的指针。空指针值转换为目标类型的空指针值。

signed charis not a base class of char, so not even this applies.

signed char不是 的基类char,所以即使这也不适用。

Therefore, an implicit, standard pointer conversion from signed charto charcannot be performed.

因此,无法执行从signed charto的隐式标准指针转换char

On the other hand, conversions between values of integral types are permitted according to what specified in Paragraph 4.7.

另一方面,根据第 4.7 节中的规定,允许整数类型值之间的转换。

回答by speeder

C++ don't have automatic pointer conversion, it does not matter what are the pointer types on each side of the assignment, if they are different, you need a cast.

C++ 没有自动指针转换,赋值的每一侧的指针类型是什么都没有关系,如果它们不同,则需要进行强制转换。

回答by Joseph Mansfield

charis a distinct type from unsigned charand signed char. It is only guaranteed to have equivalent value representation to one of them, but it is still a distinct type. You therefore cannot convert from either unsigned char*or signed char*to char*(that is, unless you use a reinterpret_cast). C++ just doesn't allow pointer conversions between distinct types like this, because then one type could masquerade as another.

char是与unsigned char和不同的类型signed char。它只保证与其中一个具有等效的值表示,但它仍然是一种不同的类型。因此,您不能从unsigned char*或转换signed char*char*(即,除非您使用 a reinterpret_cast)。C++ 只是不允许像这样的不同类型之间的指针转换,因为这样一种类型可以伪装成另一种类型。

However, a conversion from either unsigned charor signed charto charis perfectly fine because it just involves a conversion of its value.

但是,从任一unsigned charsigned char到的转换char完全没问题,因为它只涉及其值的转换。

Consider it this way: you can convert an intto a float, but you can't convert an int*to a float*.

这样考虑:您可以将 an 转换int为 a float,但不能将 an 转换int*为 a float*

回答by user1914745

I could be wrong, but as said above, when you assigned "C = S; C = U;", C++ automatically converts it, kinda like if you do "char x = "h"; printf("%i", x);". However, pointers point to a specific location in memory, and that location has a size. So while converting sort of just looks at the values from a different angles, pointing to different values may involve changing the size of the value that is being pointed at.

我可能是错的,但如上所述,当你分配 "C = S; C = U;" 时,C++ 会自动转换它,有点像你做 "char x = "h"; printf("%i", x );"。但是,指针指向内存中的特定位置,并且该位置具有大小。因此,虽然转换只是从不同角度查看值,但指向不同的值可能涉及更改所指向的值的大小。