问题
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?
回答1:
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.
回答2:
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.
回答3:
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*
.
回答4:
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.
来源:https://stackoverflow.com/questions/15046162/invalid-conversion-from-unsigned-char-to-char