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.