web-dev-qa-db-ja.com

unsigned char *からchar *への無効な変換

ここにコードがあります-

  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]

これは、Intel32ビットマシン上のUbuntu12.10のgccバージョン4.6.3でコンパイルされます。

char型はunsigned char on x86。-

非ポインタ型の7行目と8行目の割り当てに問題がない場合、10行目と11行目のポインタ型にエラーがスローされるのはなぜですか。

また、C = Uキャストを必要とせずに成功しますか?

12
nightlytrails

まず、charsigned char、およびunsigned charがすべて異なるタイプであるという事実を強調することが重要です。 C++ 11標準のセクション4.10は、異なるタイプのポインター間の3つの可能な標準ポインター変換を定義しています。

1。ヌルポインタ定数は、ゼロと評価される整数型の整数定数式(5.19)のprvalue、またはstd :: nullptr_t型のprvalueです。 nullポインター定数は、ポインター型に変換できます。結果はそのタイプのnullポインター値であり、オブジェクトポインターまたは関数ポインタータイプの他のすべての値と区別できます。このような変換は、ヌルポインタ変換と呼ばれます。同じタイプの2つのnullポインタ値は等しく比較されます。ヌルポインター定数からcv修飾型へのポインターへの変換は単一の変換であり、ポインター変換とそれに続く修飾変換(4.4)のシーケンスではありません。整数型のnullポインター定数は、std :: nullptr_t型のprvalueに変換できます。 [注:結果のprvalueはnullポインター値ではありません。 —エンドノート]

ここにはタイプnulltptr_tのnullポインターがないため、これは関係ありません。

2。タイプ「pointertocv T」(Tはオブジェクトタイプ)のprvalueは、タイプ「pointer tocvvoid」のprvalueに変換できます。 「pointertocvT」を「pointertocv void」に変換した結果は、オブジェクトがタイプTの最も派生したオブジェクト(1.8)であるかのように、タイプTのオブジェクトが存在する格納場所の開始点を示します。 (つまり、基本クラスのサブオブジェクトではありません)。 nullポインター値は、宛先タイプのnullポインター値に変換されます。

宛先タイプがvoidでないため、これは適用できません。最後に、

3。タイプ「pointertocv D」(Dはクラスタイプ)のprvalueは、タイプ「pointer to cv B」(BはDの基本クラス(第10節))のprvalueに変換できます。アクセスできない(条項11)またはあいまいな(10.2)Dの基本クラス、この変換を必要とするプログラムは形式が正しくありません。変換の結果は、派生クラスオブジェクトの基本クラスサブオブジェクトへのポインタです。 nullポインター値は、宛先タイプのnullポインター値に変換されます。

signed charcharの基本クラスではないため、これも当てはまりません。

したがって、signed charからcharへの暗黙の標準ポインタ変換は実行できません。

一方、整数型の値間の変換は、4.7項で指定されている方法に従って許可されます。

7
Andy Prowl

C++には自動ポインター変換がありません。割り当ての両側のポインターの種類は関係ありません。それらが異なる場合は、キャストが必要です。

3
speeder

charは、unsigned charおよびsigned charとは異なるタイプです。それらの1つと同等の値表現を持つことが保証されているだけですが、それでも別個のタイプです。したがって、unsigned char*またはsigned char*からchar*に変換することはできません(つまり、reinterpret_castを使用しない限り)。 C++では、このような個別の型間のポインタ変換は許可されていません。これは、ある型が別の型になりすます可能性があるためです。

ただし、unsigned charまたはsigned charからcharへの変換は、その値の変換のみを伴うため、まったく問題ありません。

このように考えてください。intfloatに変換することはできますが、int*float*に変換することはできません。

2

私は間違っているかもしれませんが、上記のように、「C = S; C = U;」を割り当てると、C++はそれを自動的に変換します。これは、「char x = "h"; printf( "%i"、x ); "。ただし、ポインタはメモリ内の特定の場所を指し、その場所にはサイズがあります。したがって、ある種の変換では、値をさまざまな角度から見るだけですが、さまざまな値を指すには、指し示す値のサイズを変更する必要があります。

0
user1914745