Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Inkompatible Typen String und AnsiString


Delete - So 22.01.17 12:37
Titel: Inkompatible Typen String und AnsiString
- Nachträglich durch die Entwickler-Ecke gelöscht -


hydemarie - Mo 23.01.17 14:36

Falsch ist ja schon das Wort "unnötigerweise" in deiner Originalfrage. Ein String ist eben nicht unbedingt ein AnsiString und ich meinerseits wüsste im Zweifelsfall schon gern, was mein Code wo wie macht, optimalerweise natürlich unabhängig von der Compilerversion. :?


Delete - Mo 23.01.17 15:07

- Nachträglich durch die Entwickler-Ecke gelöscht -


hydemarie - Mo 23.01.17 15:16

Die sind nicht unnötig. Delphi ist es schnuppe, wo du die Strings hinmachst, weswegen "aber ich benutze doch eine ANSI-Funktion" hier kein Argument ist. String in AnsiString ist potenzieller Datenverlust (und schlechter Stil).


Delete - Mo 23.01.17 15:31

- Nachträglich durch die Entwickler-Ecke gelöscht -


hydemarie - Mo 23.01.17 15:56

Musste halt 'n paar Casts mehr machen. ;)

Du "darfst" vieles. Sind dann halt möglicherweise Fehlerquellen, die nicht sein müssten.


Delete - Mo 23.01.17 18:45

- Nachträglich durch die Entwickler-Ecke gelöscht -


Sinspin - Mo 23.01.17 18:51

Routinen die rein mit AnsiString arbeiten sind nach wie vor nötig und haben nichts mit Datenverlust am Hut solange ich einen AnsiString habe, den bearbeite und wieder zurück liefere. Genausogut gibt es keinen Datenverlust wenn ich den passenden WinAPI Aufruf verwende der AnsiString Parameter erwartet.
Sollten die Ansi Funktionen selber, von Microsoft Seite, irgendwann als veraltet markiert sein und ein Termin für deren Abschaffung feststehen dann werden die Funktionen markiert sein nicht der Datentyp.
Es macht auch nach wie vor Sinn den Typ AnsiString zu verwenden wenn man Anwendungen erstellt die auf Daten zugreifen die vor der Unicode Ära enstanden sind.
user profile iconhydemarie hat folgendes geschrieben Zum zitierten Posting springen:
Musste halt 'n paar Casts mehr machen. ;)

Casten halte ich für schlechten Progammierstil und für Datenferlust Quelle nummer Eins.


Martok - Mi 25.01.17 00:23

An welcher Stelle exakt kommt die "Fehler"-Meldung eigentlich? Ich könnte mir vorstellen, dass man vergessen hat, die UpCase-Funktion passend zu überladen?

Rein von der Logik her hast du völlig Recht, im Gegensatz zu dem was der Compiler sagt ist sogar die zweite Version diejenige, die potentiellen Datenverlust hat.


Delete - Mi 25.01.17 04:02

- Nachträglich durch die Entwickler-Ecke gelöscht -


jaenicke - Mi 25.01.17 06:07

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Ich denke, ich werde die "Alias"-Bezeichnungen der Funktionen und Datentypen verwenden, dann wird jede IDE entsprechende ANSI oder UNICODE Anpassungen vornehmen, und ich brauch mich nicht weiters darum zu kümmern:
Der Weg wäre auch schon bei älteren Delphiversionen korrekt gewesen, aber leider haben sich viele nicht dran gehalten. Wenn es keinen Grund gibt eine bestimmte Variante zu verwenden, dann sollte man auch den allgemeinen Typ benutzen. Genau deshalb gab es auch schon in den ganz alten Versionen die entsprechenden Umleitungen.

Es gibt immer Fälle, in denen das nicht geht, z.B. bei einer Hardwareansteuerung oder bei der Implementierung eines Protokolls für den Datenaustausch im Internet über Sockets.

In diesen Fällen machen dann aber auch (korrekte) Casts Sinn. Damit dokumentiert man die Problematik und dass man sie korrekt implementiert hat.


Delete - Mi 25.01.17 06:50

- Nachträglich durch die Entwickler-Ecke gelöscht -


jaenicke - Mi 25.01.17 08:44

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Dennoch bleiben mir die Warnungen unverständlich.
Ich nehme mal dein Beispiel:

Delphi-Quelltext
1:
2:
3:
4:
5:
function TfrDrive.OpenVolume(ADriveLetter: AnsiChar): THandle;
var
  s: AnsiString;
begin
  s := '\\.\' + UpCase(ADriveLetter) + ':'// <--- Warnung

Was passiert ist, dass das Ergebnis von UpCase (ein AnsiString) mit zwei anderen Strings (UnicodeStrings, weil Standardstringtyp) verkettet wird. Dieses Ergebnis wird dann in einen AnsiString geschrieben.
Das heißt im Endeffekt werden die UnicodeStrings in AnsiStrings konvertiert.

Nun siehst du natürlich, dass das bei den verwendeten Zeichen kein Problem ist. Das weiß aber der Compiler nicht. Natürlich könnte der Compiler versuchen das aufwendig zu prüfen, aber warum?
So trivial ist es nicht zu prüfen, ob die Unicodezeichen korrekt in Ansi in der aktuellen Codepage aufgelöst werden können.

So könntest du das ganze auch schreiben:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
function TfrDrive.OpenVolume(ADriveLetter: AnsiChar): THandle;
const
  cPrefix: AnsiString = '\\.\';
  cSuffix: AnsiString = ':';
var
  s: AnsiString;
begin
  s := cPrefix + UpCase(ADriveLetter) + cSuffix;

So sollte keine Warnung kommen.


Delete - Mi 25.01.17 09:12

- Nachträglich durch die Entwickler-Ecke gelöscht -