简体   繁体   中英

Invalid conversion from unsigned char* to char*

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.

Considering that char type is unsigned char on 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 ?

Also, should C = U succeeds without requiring a cast?

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

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 ]

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

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.

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

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.

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

Therefore, an implicit, standard pointer conversion from signed char to char cannot be performed.

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

C ++没有自动指针转换,分配每一侧的指针类型都无关紧要,如果它们不同,则需要转换。

char is a distinct type from unsigned char and 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.

However, a conversion from either unsigned char or signed char to char is perfectly fine because it just involves a conversion of its value.

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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