Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Errschaffer

Alter Hase

  • »Errschaffer« ist der Autor dieses Themas

Beiträge: 865

Wohnort: Frankfurt

  • Private Nachricht senden

1

11.11.2008, 16:57

Speichern Funktioniert nicht

Hallo,
ich habe Porbleme Sachen abzuspeichern...


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
void Speichern (int *pHighscore_Spieler1,int *pHighscore_Spieler2,int *pHighscore_Pc)
{
    ofstream Output ("Highscore.hsc", ios::binary);
    Output.write ( (char*) &Highscore_Spieler1; sizeof (Highscore_Spieler1));
    Output.close ();




}




1>e:\porgrammieren\c++\projekte\tic-tac-toe\tic-tac-toe\main.cpp(291) : error C2065: 'Highscore_Spieler1': nichtdeklarierter Bezeichner
1>e:\porgrammieren\c++\projekte\tic-tac-toe\tic-tac-toe\main.cpp(291) : error C2143: Syntaxfehler: Es fehlt ')' vor ';'
1>e:\porgrammieren\c++\projekte\tic-tac-toe\tic-tac-toe\main.cpp(291) : error C2065: 'Highscore_Spieler1': nichtdeklarierter Bezeichner
1>e:\porgrammieren\c++\projekte\tic-tac-toe\tic-tac-toe\main.cpp(291) : error C2059: Syntaxfehler: ')'
1>e:\porgrammieren\c++\projekte\tic-tac-toe\tic-tac-toe\main.cpp(291) : error C2070: ''unknown-type'': Ungültiger sizeof-Operand


Was kenn denn da falsch sein?

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

2

11.11.2008, 17:05

Re: Speichern Funktioniert nicht

Zitat von »"Errschaffer"«


Was kenn denn da falsch sein?


So gut wie alles!

1.

Zitat

error C2065: 'Highscore_Spieler1': nichtdeklarierter Bezeichner

Es heißt ja auch pHighscore_Spieler1.

2.

C-/C++-Quelltext

1
(char*)&Highscore_Spieler1


Vermutlich meintest du eher: ( const char* )pHighscore_Spieler1?!

3.

C-/C++-Quelltext

1
sizeof (Highscore_Spieler1) 


Nein, nein!!! Das geht so nicht. Richtig wäre:

C-/C++-Quelltext

1
sizeof(int)


Oder:

C-/C++-Quelltext

1
sizeof(*pHighscore_Spieler1)


Falls hinter pHighscore_Spieler1 ein Array von Daten ist muss der sizeof() Operator noch mit der Anzahl der Einträge multipliziert werden.
@D13_Dreinig

3

11.11.2008, 17:10

C-/C++-Quelltext

1
(char*) &pHighscore_Spieler1
Da sollte man aufpassen. Aber reinterpret_cast ist in C++ das Mindeste.

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

4

11.11.2008, 17:14

Zitat von »"Nexus"«

Da sollte man aufpassen. Aber reinterpret_cast ist in C++ das Mindeste.


Wieso?
@D13_Dreinig

Errschaffer

Alter Hase

  • »Errschaffer« ist der Autor dieses Themas

Beiträge: 865

Wohnort: Frankfurt

  • Private Nachricht senden

5

11.11.2008, 17:18

Ok das ich jeweils das p vergessen habe. ...habe ich verbessert.
Und wieso soll ich const char verwenden? Im Buch stehts anders.
Funktioniert aber trotzdem noch net.

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

6

11.11.2008, 17:21

Zitat von »"Errschaffer"«


Und wieso soll ich const char verwenden? Im Buch stehts anders.


Dann stehts eben im Buch falsch, die Methode ist nämlich folgend deklariert:

C-/C++-Quelltext

1
basic_ostream<charT,traits>& write(const char_type* s, streamsize n);
@D13_Dreinig

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

7

11.11.2008, 17:23

Oh je, selten so schlimmen Code gesehen.
Zudem sagt dir der Compiler doch, was falsch ist.
Da ist ein Semikolon, wo ein Komma hingehört.
Und du speicherst die Adresse eines Zeigers, was völliger Quatsch ist. Ist bislang wohl noch niemandem aufgefallen.

8

11.11.2008, 19:32

Zitat von »"David_pb"«

Zitat von »"Nexus"«

Da sollte man aufpassen. Aber reinterpret_cast ist in C++ das Mindeste.


Wieso?
Weil C++ nicht umsonst die unterschiedlichen Casts bereitstellt. Mit den C-Klammercasts wird auf irgendeine Weise versucht, etwas umzuwandeln. Bestenfalls wird eine Standardkonvertierung angewendet (was in C++ dem static_cast entsprechen würde), jedoch kann genauso ein const_cast oder reinterpret_cast (also Zeigerumbiegung) stattfinden, ohne dass man es will.

Mit reinterpret_cast sagt man ausdrücklich, dass man Gewalt anwendet. Schlimmer ist es jedoch, wenn man die Funktionalität eines static_cast will, aber den Klammercast anwendet - man erfährt unter Umständen gar nicht, dass keine Standardkonvertierung dazu existiert.

Davon abgesehen sieht man bei den C++-Castoperatoren gleich, welche Art von Umwandlung angewandt wird, und dass eine Umwandlung stattfindet. In komplexeren Ausdrücken dürfte es schon genügend Klammern haben, sodass der C-Cast leicht untergehen kann.

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

9

11.11.2008, 20:14

Zitat von »"Nexus"«

Weil C++ nicht umsonst die unterschiedlichen Casts bereitstellt.


Was erstmal kein Grund ist diese auch zu nutzen.


Zitat von »"Nexus"«

Mit den C-Klammercasts wird auf irgendeine Weise versucht, etwas umzuwandeln. Bestenfalls wird eine Standardkonvertierung angewendet (was in C++ dem static_cast entsprechen würde),


Nein, das stimmt nicht. Ein C-Cast hat gar nicht die Möglichkeit auf irgendeine Weise Casts vor zu nehmen:

C-/C++-Quelltext

1
2
3
4
5
6
struct foo
{
};

foo x;
int y = ( int )x;


Geht z.B. schon mal gar nicht...

Zitat von »"Nexus"«


jedoch kann genauso ein const_cast oder reinterpret_cast (also Zeigerumbiegung) stattfinden, ohne dass man es will.


Da ein static_cast<> so ziemlich die Selben Möglichkeiten hat wie ein C-Cast (mit Ausnahme des entfernen der Konstanz/volatileness eines Ausdrucks) ist das Verhalten mehr oder weniger austauschbar, wenn die Kontanz/volatileness keine all zu wichtige Rolle spielt.

Zitat von »"Nexus"«


Mit reinterpret_cast sagt man ausdrücklich, dass man Gewalt anwendet.


Genau, und diese "Gewalt" ist unsicher. Egal ob mit C-Cast oder reinterpret_cast. Letzterer muss nämlich ebenfalls keinen Fehlerbericht rausgeben, sondern castet fröhlich Alles in Alles. Dazu ist das Ergebnis von reinterpret_cast<> implementationsabhängig, ergo nicht (oder selten) portabel.

Zitat von »"Nexus"«


Schlimmer ist es jedoch, wenn man die Funktionalität eines static_cast will, aber den Klammercast anwendet - man erfährt unter Umständen gar nicht, dass keine Standardkonvertierung dazu existiert.


Sollte der Fall mal eintreten erfährst du das sowiso nicht, zumindest nicht beim Casten (ob der Compiler zur compilierzeit Warnungen ausspuckt liegt bei ihm). Der einzige Operator der eine Prüfung vor nimmt (und deshalb sehr langsam sein kann [und RTTI fordert]) ist dynamic_cast<>.
@D13_Dreinig

10

11.11.2008, 21:06

Zitat von »"David_pb"«

Zitat von »"Nexus"«

Mit den C-Klammercasts wird auf irgendeine Weise versucht, etwas umzuwandeln. Bestenfalls wird eine Standardkonvertierung angewendet (was in C++ dem static_cast entsprechen würde),
Nein, das stimmt nicht. Ein C-Cast hat gar nicht die Möglichkeit auf irgendeine Weise Casts vor zu nehmen

Ich denke, du weisst, was ich damit gemeint habe (mal abgesehen davon, dass ich geschrieben habe, "es wird versucht"). :roll:

Zitat von »"David_pb"«

Da ein static_cast<> so ziemlich die Selben Möglichkeiten hat wie ein C-Cast (mit Ausnahme des entfernen der Konstanz/volatileness eines Ausdrucks) ist das Verhalten mehr oder weniger austauschbar, wenn die Kontanz/volatileness keine all zu wichtige Rolle spielt.

Das ist völlig falsch. Erstens mal ist gerade die Funktion des reinterpret_cast auch im C-Cast enthalten. Man kann also zum Beispiel Folgendes schreiben, was mit static_cast nicht geht:

C-/C++-Quelltext

1
2
  int* p;
  int i = (int)p;

Zweitens ist es eben gerade nicht austauschbar, und zwar weil CV-Correctness in C++ eine wichtige Bedeutung hat und weil man sich mit C-Casts Dinge angewöhnt, die fehleranfällig sind. Wenn man in "harmlosen" Ausdrücken klammercastet, wird man auch nicht so schnell erkennen, wann etwas "gefährlich" ist. Und wieso nicht von Anfang an die sichere Variante lernen?

Zitat von »"David_pb"«

Zitat von »"Nexus"«

Mit reinterpret_cast sagt man ausdrücklich, dass man Gewalt anwendet.
Genau, und diese "Gewalt" ist unsicher. Egal ob mit C-Cast oder reinterpret_cast. Letzterer muss nämlich ebenfalls keinen Fehlerbericht rausgeben, sondern castet fröhlich Alles in Alles. Dazu ist das Ergebnis von reinterpret_cast<> implementationsabhängig, ergo nicht (oder selten) portabel.

Ja, aber im Gegensatz zu C-Casts weiss man bei reinterpret_cast, dass Gewalt angewendet wird, während C-Casts alles bedeuten können. Dass das Resultat undefiniert sein kann, stimmt zwar, ist aber bei C-Casts nicht anders. Und um wie du alles wörtlich zu nehmen: "alles in alles" stimmt ebenfalls nicht. reinterpret_cast kann weniger als C-Casts und ist auf die gefährlichen Einsatzbereiche spezialisiert. Er kann nämlich das, was static_cast und const_cast können, nicht.

Zitat von »"David_pb"«

Zitat von »"Nexus"«

Schlimmer ist es jedoch, wenn man die Funktionalität eines static_cast will, aber den Klammercast anwendet - man erfährt unter Umständen gar nicht, dass keine Standardkonvertierung dazu existiert.
Sollte der Fall mal eintreten erfährst du das sowiso nicht, zumindest nicht beim Casten (ob der Compiler zur compilierzeit Warnungen ausspuckt liegt bei ihm).

Wiederum falsch. Mit static_cast geht beispielsweise oben genanntes Codebeispiel nicht, ohne zur Compilezeit einen Fehler zu erhalten:

C-/C++-Quelltext

1
2
  int* p;
  int i = static_cast<int>(p);

Oder das:

C-/C++-Quelltext

1
2
  const int c = func();  // func() gibt einen int zurück - um Compiler-Optimierung zu umgehen  

  int& d = static_cast<int&>(c);

Mit Klammercast gehen übrigens beide - ohne jegliche Warnung.

Ich kann ehrlich gesagt nicht ganz verstehen, wieso du dich so stur gegen die C++-Operatoren wehrst, zumal aus meiner Sicht bereits Erkennbarkeit für sie sprechen sollte. Wirklich Argumente gegen sie hast du ja keine gebracht.

Werbeanzeige