Static-cast von char* zu unsigned char*
-
Hallo an alle,
ich bin heute auf folgendes Problem gestossen:
int main() { char* pC = "Hello World"; unsigned char* pUC = static_cast< unsigned char* >( pC ); }Bevor ich den Code kompiliert habe, dachte ich noch, das wäre kein Problem. Allerdings sieht das der Compiler komplett anders.
1>Main.cpp
1>c:\dokumente und einstellungen\LordHong\eigene dateien\mytestarea\testproject\main.cpp(42) : error C2440: 'static_cast' : cannot convert from 'char *' to 'unsigned char *'
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style castDumm ist nun, das ich nicht verstehe, was ihn nun stört. Natürlich klappt es wenn ich einen reinterpret_cast benutze. Allerdings ist meine Verwunderung immer noch nicht aus meinem Gesicht verschwunden.
Was stört den Compiler? Warum kann ich den Zeiger von char* nicht auf unsigned char* umcasten? Was meint der Compiler mit "Types pointed to are unrelated"?
Danke im Voraus für Eure Hilfe.
Gruß
Lord Hong
-
damit meint er, dass die zwei typen nun eben zwei (unterschiedliche) typen sind.
genauso wird dir eindouble* foo (int* i) { return static_cast<double>(i); }um die ohren fliegen.
netterweise schlägt dir dein compiler auch gleich eine lösung vor

/edit: code-tags repariert
-
Hallo queer_boy,
nun habe ich allerdings eine anderes Problem. Was verstehst du unter einen Typen?
Als Build-In Typen verstehe ich int, double, float, bool, long etc.
Aber einen Zeiger auf eine Typ verstehe ich nicht als Typ. Für mich ist char* ein Zeiger auf den Typ Character.
In deinem Beispiel lautet die Fehlermeldung auch anders:
1>c:\dokumente und einstellungen\LordHong\eigene dateien\mytestarea\testproject\main.cpp(39) : error C2440: 'static_cast' : cannot convert from 'int *' to 'double'
1> There is no context in which this conversion is possibleMist, das verstehe ich immer noch nicht. Bin ich nun wieder im ersten Semester gelandet.

Nach meinem Verständnis hätte auch dein Code kompilieren müssen. foo nimmt den Zeiger auf einen Integer. Dann hätte nicht der Wert in ein Double gecastet werden müssen, wohin es zeigt, sondern die Adresse wohin gezeigt wird. Aber der Compiler verweigert die Arbeit.
Ich habe es erstmal nicht verstanden, aber Danke, dass du mir was zu denken gegeben hast.
Gruß
Lord Hong
-
queer_boy schrieb:
damit meint er, dass die zwei typen nun eben zwei (unterschiedliche) typen sind.
genauso wird dir eindouble* foo (int* i) { return static_cast<double>(i); }um die ohren fliegen.
netterweise schlägt dir dein compiler auch gleich eine lösung vor

/edit: code-tags repariert
Sollte wohl double* sein, oder?
-
Auch Zeiger sind Typen. Nämlich Typ "Zeiger auf Typ X".
Und so wenig wie int und double verwandt sind, sind int* und double verwandt, oder int* und double*.
Was ist denn jetzt das Problem darin, reinterpret_cast zu verwenden?

-
Ich finde das auch eine völlig bescheuerte Regelung. Müsste nicht auch laut Standard
sizeof(int)==sizeof(unsigned int)gegeben sein? Ein reinterpret_cast ist eigentlich für "riskante" Umwandlungen da, während char*->unsigned char* völlig Pipi ist, einfach risikolos.
-
Hi,
nun ist mir auch klar warum es problematisch ist und warum es mit einem static_cast nicht klappen kann.
int main() { int i = 65000; int* pI = &i; char* pC = reinterpret_cast<char*>( pI ); for (int i = 0; i < sizeof( int ); ++i ) std::cout << "Value: " << pC[i] << std::endl; }@LordJaxom
S. Beispiel oben, des Wegen meide ich reinterpret_casts.@Badestrand
Von deiner Denkstruktur habe ich wohl was übernommen. Auch ich ging die ganze Zeit davon aus das ein char und ein unsigned char ein Byte groß seien.Ein char* zu einem unsigned char* enfand ich als unkompliziert, weil beide die gleiche Größe haben. Nun bin ich mir aber auch nicht mehr sicher, da ein int* zu einem char* mit Informationsverluste behaftet ist.
Anscheinend caste ich zu selten.

Vielen Dank an alle.
Lord Hong
-
Fellhuhn schrieb:
queer_boy schrieb:
damit meint er, dass die zwei typen nun eben zwei (unterschiedliche) typen sind.
genauso wird dir eindouble* foo (int* i) { return static_cast<double>(i); }um die ohren fliegen.
netterweise schlägt dir dein compiler auch gleich eine lösung vor

/edit: code-tags repariert
Sollte wohl double* sein, oder?
dummer fehler, ja. führte leider zu noch mehr unklarheiten ^^'
Badestrand schrieb:
Ich finde das auch eine völlig bescheuerte Regelung. Müsste nicht auch laut Standard sizeof(int)==sizeof(unsigned int) gegeben sein? Ein reinterpret_cast ist eigentlich für "riskante" Umwandlungen da, während char*->unsigned char* völlig Pipi ist, einfach risikolos.
ist es nicht. werte können völlig unterschiedlich dargestellt werden; das einzig absurde könnte sein, dass char womöglich "tatsächlich" unsigned char ist (wenn nicht, dann signed char) - nichtsdestotrotz sind es unterschiedliche typen, und das ist einer der (wenigen) berechtigten und wohldefinierten einsatzmöglichkeiten für einen reinterpret_cast,
lord.hong schrieb:
int main() { int i = 65000; int* pI = &i; char* pC = reinterpret_cast<char*>( pI ); for (int i = 0; i < sizeof( int ); ++i ) std::cout << "Value: " << pC[i] << std::endl; }@LordJaxom
S. Beispiel oben, des Wegen meide ich reinterpret_casts.genauso wie dieser cast. genau dazu gibt es auf dieser seite in der übersicht noch einen weiteren thread, wo ich 3.10/15 zitiere.
@Badestrand
Von deiner Denkstruktur habe ich wohl was übernommen. Auch ich ging die ganze Zeit davon aus das ein char und ein unsigned char ein Byte groß seien.ein char hat die größe eines bytes, aber nur per definitionem. (und ein byte hat exact
numeric_limits<char>::digits()bits)Ein char* zu einem unsigned char* enfand ich als unkompliziert, weil beide die gleiche Größe haben. Nun bin ich mir aber auch nicht mehr sicher, da ein int* zu einem char* mit Informationsverluste behaftet ist.
wenn du es wieder rückverwandelst, sollte es denselben wert darstellen.
-
Wieso wurden überhaupt drei Typen für Charaktere eingeführt (
char,signed char,unsigned char)? Wäre es nicht einfacher gewesen, wenigstens hier konsequent zu sein und es gleich wie beishort,intundlongzu regeln?wchar_tist z.B. wieder eine Sache für sich...queer_boy schrieb:
genau dazu gibt es auf dieser seite in der übersicht noch einen weiteren thread, wo ich 3.10/15 zitiere.
Das wäre dann dieser hier.

-
queer_boy schrieb:
Badestrand schrieb:
Ich finde das auch eine völlig bescheuerte Regelung. Müsste nicht auch laut Standard sizeof(int)==sizeof(unsigned int) gegeben sein? Ein reinterpret_cast ist eigentlich für "riskante" Umwandlungen da, während char*->unsigned char* völlig Pipi ist, einfach risikolos.
ist es nicht. werte können völlig unterschiedlich dargestellt werden; das einzig absurde könnte sein, dass char womöglich "tatsächlich" unsigned char ist (wenn nicht, dann signed char) - nichtsdestotrotz sind es unterschiedliche typen, und das ist einer der (wenigen) berechtigten und wohldefinierten einsatzmöglichkeiten für einen reinterpret_cast,
"int*"<->"unsigned int*" sind zwar verschiedene Typen aber meiner Meinung nach "weniger unterschiedlich" als z.B. "int*"<->"double*". Aber gut, das ist vielleicht Anssichtssache, ich jedenfalls hätte mir hier einen static-cast gewünscht. Einen reinterpret-cast verbinde ich immer mit "Unreinheit", während mir diese Konvertierung sehr "rein" vorkommt. Wie auch immer..

-
queer_boy schrieb:
Fellhuhn schrieb:
queer_boy schrieb:
damit meint er, dass die zwei typen nun eben zwei (unterschiedliche) typen sind.
genauso wird dir eindouble* foo (int* i) { return static_cast<double>(i); }um die ohren fliegen.
netterweise schlägt dir dein compiler auch gleich eine lösung vor

/edit: code-tags repariert
Sollte wohl double* sein, oder?
dummer fehler, ja. führte leider zu noch mehr unklarheiten ^^'
Ach natürlich! Super ihr zwei! Nun ist es auch mir klar, warum das Ganze nur mit einem reinterpret_cast funktionieren kann!
