Discussion:
SetCodePage nicht (mehr) für AnsiString?
(zu alt für eine Antwort)
Jens Lenge
2012-09-10 00:42:06 UTC
Permalink
Hallo Welt, gemäß "Delphi in a Unicode World II" kann die Codepage von
AnsiStrings mittels "SetCodePage" beeinflusst werden; siehe

http://edn.embarcadero.com/article/38498#10SetCodePage

Mein real existierendes Delphi XE3 bietet "SetCodePage" aber
ausschließlich für RawByteStrings an. Irgendwie leuchtet mir die Logik
dahinter nicht wirklich ein:

a) Ein AnsiString kann doch eigentlich viele verschiedene Codepages
haben. Wie kann ich beeinflussen, welche tatsächlich benutzt wird?

b) Ein RawByteString hat laut Doku die feste Codepage $FFFF als
Kennzeichen "keiner" Codepage. Wieso kann ich dann dennoch eine frei
gewählte Codepage setzen?

Wer kann mich aufklären?
Hans-Peter Diettrich
2012-09-10 04:11:17 UTC
Permalink
Post by Jens Lenge
Hallo Welt, gemäß "Delphi in a Unicode World II" kann die Codepage von
AnsiStrings mittels "SetCodePage" beeinflusst werden; siehe
http://edn.embarcadero.com/article/38498#10SetCodePage
Mein real existierendes Delphi XE3 bietet "SetCodePage" aber
ausschließlich für RawByteStrings an. Irgendwie leuchtet mir die Logik
a) Ein AnsiString kann doch eigentlich viele verschiedene Codepages
haben. Wie kann ich beeinflussen, welche tatsächlich benutzt wird?
b) Ein RawByteString hat laut Doku die feste Codepage $FFFF als
Kennzeichen "keiner" Codepage. Wieso kann ich dann dennoch eine frei
gewählte Codepage setzen?
Wer kann mich aufklären?
Also, das ist so wie bei den Blümchen und den Bienchen ;-)
Es gibt da zwei Arten von Menschen^W Encodings, ein statisches und ein
dynamisches.

Jeder AnsiString hat ein vordefiniertes und unveränderbares (statisches)
Encoding. Dies ist deshalb so wichtig, weil ein leerer AnsiString keine
weitere Information über sein Encoding besitzt.

Das zusammen mit den String-Daten gespeicherte (dynamische) Encoding
wiederum ist wichtig bei Ausdrücken, die keiner Variablen zugeordnet sind.

Bei der Zuweisung eines Strings an eine Variable wird der Ausdruck ggf.
in das *statische* Encoding der Variablen konvertiert.

RawByteStrings haben o.g. *statisches* Encoding ($FFFF), aber ein
variables dynamisches Encoding. Bei der Zuweisung eines Strings an eine
RawByteString Variable findet keine Konvertierung statt, es wird auch
nichts kopiert, er zeigt danach einfach auf den übergebenen String.
GetCodePage liefert dann das dynamische Encoding dieses Strings, und mit
SetCodePage kann dann dieses Encoding geändert werden - der
RawByteString zeigt danach auf den konvertierten String.

Bei SetCodePage kann zusätzlich angegeben werden, ob der String
tatsächlich konvertiert werden soll, oder ob er nur in ein anderes
Encoding "gecastet" werden soll. Letzteres kann dazu verwendet werden,
einem falsch eingelesenen String nachträglich das richtige Encoding zu
verpassen.

DoDi
Jens Lenge
2012-09-10 14:40:50 UTC
Permalink
Post by Hans-Peter Diettrich
Also, das ist so wie bei den Blümchen und den Bienchen ;-)
:)
Post by Hans-Peter Diettrich
Jeder AnsiString hat ein vordefiniertes und unveränderbares (statisches)
Encoding. Dies ist deshalb so wichtig, weil ein leerer AnsiString keine
weitere Information über sein Encoding besitzt. [...]
Das interpretiere ich jetzt so:

a) Wenn ich irgendwo "var s: AnsiString;" schreibe, dann ist *damit* das
Encoding bereits unveränderlich festgelegt (auch wenn der eigentliche
Stringinhalt erst später zugewiesen wird).

b) Wenn dann später "s := <whatever>;" geschrieben steht und <whatever>
ein anderes Encoding besitzt, dann wird bei der Zuweisung <whatever>
zunächst in das bestehende statische Encoding von s konvertiert.

c) Einzige Ausnahme: Falls das statische Encoding von s den Wert $FFFF
hat (vulgo: RawByteString), dann wird bei einer Zuweisung *nicht*
konvertiert, sondern <whatever> einfach "as is" übernommen.

Soweit richtig?
Dann würd' ich gern noch ein paar Thesen/Rückfragen nachschießen:

1.) Hier[tm] liefert StringCodePage(s) für AnsiStrings auf allen PCs
immer Windows-1252.
- Ist dies unter Windows *immer* so oder hängt es von der Sprachversion
bzw. den Spracheinstellungen des Systems/des Benutzers ab und kann sich
daher jederzeit ändern, ohne dass mein Delphi-Programm darauf Einfluss hat?
- Und falls es sich ändern kann: Wenn mein Programm erst einmal
kompiliert ist (z. B. mit AnsiString als Windows-1252), ist das Encoding
dann für dieses Programm unveränderlich (statisch einkompiliert) - oder
wird es dynamisch vom System erfragt und kann sich sogar zwischen zwei
Programmstarts ändern?

2.) UTF8String = AnsiString(65001) und RawByteString = AnsiString(65535)
sind nichts anderes als AnsiStrings mit vom Default abweichenden
statischem Encoding. In gleicher Weise könnte man auch definieren:

type TConsoleString = AnsiString(850);
var my_console_string: TConsoleString;

Oder auch direkt:

var my_console_string: AnsiString(850);

In beiden Fällen würden Zuweisungen an my_console_string immer
automatisch in Codepage 850 umkodiert. Richtig?

3.) Wenn man nicht explizit ein Encoding vorgibt, also nur "var s:
AnsiString;" schreibt, dann wird dies als "AnsiString(0)" aufgefasst und
damit die aktuelle Codepage des Systems verwendet (hier also
Windows-1252, siehe Punkt 1.). Richtig?
Hans-Peter Diettrich
2012-09-11 09:12:48 UTC
Permalink
Post by Jens Lenge
Post by Hans-Peter Diettrich
Also, das ist so wie bei den Blümchen und den Bienchen ;-)
:)
Post by Hans-Peter Diettrich
Jeder AnsiString hat ein vordefiniertes und unveränderbares (statisches)
Encoding. Dies ist deshalb so wichtig, weil ein leerer AnsiString keine
weitere Information über sein Encoding besitzt. [...]
a) Wenn ich irgendwo "var s: AnsiString;" schreibe, dann ist *damit* das
Encoding bereits unveränderlich festgelegt (auch wenn der eigentliche
Stringinhalt erst später zugewiesen wird).
Ja, in diesem Fall als AnsiString(0) = AnsiString(CP_ACP). Da aber
CP_ACP auch nur ein Platzhalter für eine Codepage ist, könnte
GetStringEncoding anschließend auch eine andere (die tatsächlich
verwendete) Codepage angeben.
Post by Jens Lenge
b) Wenn dann später "s := <whatever>;" geschrieben steht und <whatever>
ein anderes Encoding besitzt, dann wird bei der Zuweisung <whatever>
zunächst in das bestehende statische Encoding von s konvertiert.
c) Einzige Ausnahme: Falls das statische Encoding von s den Wert $FFFF
hat (vulgo: RawByteString), dann wird bei einer Zuweisung *nicht*
konvertiert, sondern <whatever> einfach "as is" übernommen.
Soweit richtig?
Ja :-)
Post by Jens Lenge
1.) Hier[tm] liefert StringCodePage(s) für AnsiStrings auf allen PCs
immer Windows-1252.
Siehe oben.
Post by Jens Lenge
- Ist dies unter Windows *immer* so oder hängt es von der Sprachversion
bzw. den Spracheinstellungen des Systems/des Benutzers ab und kann sich
daher jederzeit ändern, ohne dass mein Delphi-Programm darauf Einfluss hat?
Das hängt ziemlich sicher von der Spracheinstellung des Benutzers ab. In
Ländern, deren Alphabet nicht auf dem lateinischen beruht (Griechenland,
Russland...) ist eine Latin Codepage wenig sinnvoll.
Post by Jens Lenge
- Und falls es sich ändern kann: Wenn mein Programm erst einmal
kompiliert ist (z. B. mit AnsiString als Windows-1252), ist das Encoding
dann für dieses Programm unveränderlich (statisch einkompiliert) - oder
wird es dynamisch vom System erfragt und kann sich sogar zwischen zwei
Programmstarts ändern?
Siehe oben.
Post by Jens Lenge
2.) UTF8String = AnsiString(65001) und RawByteString = AnsiString(65535)
sind nichts anderes als AnsiStrings mit vom Default abweichenden
type TConsoleString = AnsiString(850);
var my_console_string: TConsoleString;
var my_console_string: AnsiString(850);
In beiden Fällen würden Zuweisungen an my_console_string immer
automatisch in Codepage 850 umkodiert. Richtig?
Ja.
Post by Jens Lenge
AnsiString;" schreibt, dann wird dies als "AnsiString(0)" aufgefasst und
damit die aktuelle Codepage des Systems verwendet (hier also
Windows-1252, siehe Punkt 1.). Richtig?
Siehe oben.

DoDi
Jens Lenge
2012-09-11 09:03:47 UTC
Permalink
Erstmal Danke für die umfangreiche Aufklärung - ich denke, das habe ich
Post by Hans-Peter Diettrich
Post by Jens Lenge
- Und falls es sich ändern kann: Wenn mein Programm erst einmal
kompiliert ist (z. B. mit AnsiString als Windows-1252), ist das
Encoding dann für dieses Programm unveränderlich (statisch
einkompiliert) - oder wird es dynamisch vom System erfragt und kann
sich sogar zwischen zwei Programmstarts ändern?
Siehe oben.
Dazu sagt "oben" nichts (oder ich übersehe es). Geschieht die
Abfrage/Zuweisung der Codepage zu eiunem AnsiString via CP_ACP nun a)
statisch zur Compilezeit oder b) dynamisch zur Laufzeit.

Bei a) könnte sich das tatsächlich verwendete Encoding nur nach einem
Neukompilieren ändern, bei b) hingegen bei jedem Programmstart.

(Und ganz theoretisch - falls der Benutzer die OS-Spracheinstellung
ändert, *während* mein Programm gerade läuft, sogar innerhalb des
laufenden Programms...)
Soeren Muehlbauer
2012-09-11 10:19:40 UTC
Permalink
Hi,
Post by Jens Lenge
Dazu sagt "oben" nichts (oder ich übersehe es). Geschieht die
Abfrage/Zuweisung der Codepage zu eiunem AnsiString via CP_ACP nun a)
statisch zur Compilezeit oder b) dynamisch zur Laufzeit.
Wann immer eine Konvertierung notwendig ist, also dynamisch.


Sören
Jens Lenge
2012-09-11 14:40:21 UTC
Permalink
Post by Soeren Muehlbauer
Wann immer eine Konvertierung notwendig ist, also dynamisch.
Ich wittere ein Missverständnis. Ich verwende mal DoDis Vokabular mit
"statischem" und "dynamischem" Encoding:
Es geht *nicht* darum, wann ein String-Inhalt von seinem "dynamischen"
Encoding in das "statische" Encoding einer AnsiString-Variablen
konvertiert wird, sondern es geht um die Festlegung des "statischen"
Encodings einer Variablen selbst.

Szenario:
* Die Funktion Foo meines Delphi-Programms verwendet ein "var s:
AnsiString;".
* Dies ist gleichbedeutend mit "AnsiString(0)", d. h. das "statische"
Encoding von s richtet sich nach der aktuellen Codepage des Systems.
* Zum Zeitpunkt des Kompilierens sei die aktuelle Systemcodepage z. B.
Windows-1252.

Was gilt nun?

a) Die zur Compilezeit gültige aktuelle Systemcodepage (hier z. B.
Windows-1252) wird fest mit einkompiliert. Wenn ich das kompilierte
Programm später starte, wird "s" immer mit Windows-1252 arbeiten - auch
dann, wenn auf dem Ziel-PC eine andere Systemcodepage eingestellt ist.

b) Die aktuelle Systemcodepage wird bei jedem Start meines
Delphi-Programms neu abgefragt, d. h. "s" verwendet ggf. bei jedem
Programmstart ein anderes Encoding (je nach der gerade gültigen
Systemcodepage). Dabei spielt es keine Rolle, wie die Einstellung zur
Compilezeit war.

c) Die aktuelle Systemcodepage wird bei jedem Aufruf der Funktion Foo
neu ermittelt, d. h. das Encoding von "s" kann auch *während* der
Programmausführung wechseln, falls der Benutzer zwischenzeitlich die
Systemeinstellungen ändert.

Ist die Frage so klarer?
Hans-Peter Diettrich
2012-09-11 15:50:00 UTC
Permalink
Post by Jens Lenge
Erstmal Danke für die umfangreiche Aufklärung - ich denke, das habe ich
Post by Hans-Peter Diettrich
Post by Jens Lenge
- Und falls es sich ändern kann: Wenn mein Programm erst einmal
kompiliert ist (z. B. mit AnsiString als Windows-1252), ist das
Encoding dann für dieses Programm unveränderlich (statisch
einkompiliert) - oder wird es dynamisch vom System erfragt und kann
sich sogar zwischen zwei Programmstarts ändern?
Siehe oben.
Dazu sagt "oben" nichts (oder ich übersehe es). Geschieht die
Abfrage/Zuweisung der Codepage zu eiunem AnsiString via CP_ACP nun a)
statisch zur Compilezeit oder b) dynamisch zur Laufzeit.
Natürlich dynamisch zur Laufzeit, so wie auf der jeweiligen Maschine
eingestellt.
Post by Jens Lenge
Bei a) könnte sich das tatsächlich verwendete Encoding nur nach einem
Neukompilieren ändern, bei b) hingegen bei jedem Programmstart.
(Und ganz theoretisch - falls der Benutzer die OS-Spracheinstellung
ändert, *während* mein Programm gerade läuft, sogar innerhalb des
laufenden Programms...)
Das wiederum ist relativ unwahrscheinlich. Dann gäbe es ja plötzlich
AnsiString(0) mit verschiedenen Encodings im Speicher. Wenn's Dich
interessiert, warum probierst Du das nicht einfach selbst aus? Mit allen
Delphi-Versionen, die können ja unterschiedlich reagieren...

DoDi
Jens Lenge
2012-09-11 15:24:51 UTC
Permalink
Post by Hans-Peter Diettrich
Natürlich dynamisch zur Laufzeit, so wie auf der jeweiligen Maschine
eingestellt.
Ok, danke für die Info.
Post by Hans-Peter Diettrich
Das wiederum ist relativ unwahrscheinlich. Dann gäbe es ja plötzlich
AnsiString(0) mit verschiedenen Encodings im Speicher.
Ja, genau darauf wollte ich hinaus.

(Allerdings kann das auch dann passieren, wenn zwei Instanzen des
Programms zu verschiedenen Zeiten gestartet werden und dann parallel
laufen. Die Systemcodepage könnte sich ja zwischen den Programmstarts
geändert haben.)

Also ist es _vermutlich_ so:
* Dynamische Abfrage der Systemcodepage ja, aber nur einmal zu Programmstart
* Danach dann während des Programmablaufs unveränderlich
Post by Hans-Peter Diettrich
Wenn's Dich interessiert, warum probierst Du das nicht einfach selbst aus? Mit allen Delphi-Versionen, die können ja unterschiedlich reagieren...
Weil ich 1. nur begrenzt viele Windows- und Delphi-Versionen verfügbar
habe und das 2. auch keine allgemeingültige Aussage für die übrigen
möglichen Kombinationen liefern würde. ;)
Jens Lenge
2012-10-21 20:57:19 UTC
Permalink
Post by Jens Lenge
type TConsoleString = AnsiString(850);
var my_console_string: TConsoleString;
var my_console_string: AnsiString(850);
Ja.
Da muss ich nochmal drauf zurückkommen:
Beides funktioniert im real eexistierenden Delphi XE3 nicht. Jeder
Versuch, "AnsiString(x)" als Typbezeichung zu verwenden, liefert einen
Compilerfehler. Darf/kann/soll das so sein?
Arno Garrels
2012-10-22 04:43:19 UTC
Permalink
Jeder Versuch, "AnsiString(x)" als Typbezeichung zu verwenden,
liefert einen Compilerfehler.
{code}
type
CP850String = type AnsiString(850);
{code}

--
Arno
Jens Lenge
2012-10-22 19:53:45 UTC
Permalink
Post by Arno Garrels
{code}
type
CP850String = type AnsiString(850);
{code}
Ja, so funktioniert's. Danke! :) Eine direkte Variablendeklaration geht
allerdings weder mit noch ohne "type":
1.) var MyVar: AnsiString(850); // Fehler
2.) var MyVar: type AnsiString(850); // Auch Fehler

Außerdem: Ist "type Txxx = type Tyyy;" denn eine übliche Syntax?
(Ich kannte bislang immer nur "type Txxx = Tyyy;".)

Gerade mal probiert:
a) type TMyType1 = Integer; // Geht
b) type TMyType2 = type Integer; // Geht auch

Sind a) und b) synomyn/äquivalent?
Und - falls ja - warum geht es dann bei "AnsiString(x)" nicht ohne "type"?
Arno Garrels
2012-10-23 16:31:17 UTC
Permalink
Post by Jens Lenge
Post by Arno Garrels
{code}
type
CP850String = type AnsiString(850);
{code}
Ja, so funktioniert's. Danke! :) Eine direkte Variablendeklaration
1.) var MyVar: AnsiString(850); // Fehler
2.) var MyVar: type AnsiString(850); // Auch Fehler
Warum sollte das auch funktionieren? Eine Typdeklaration ist
keine Variablendeklaration, letztere erfordert die Angabe eines
deklarierten Types, warum sollte das also bei AnsiStrings anders
sein?
Post by Jens Lenge
Außerdem: Ist "type Txxx = type Tyyy;" denn eine übliche Syntax?
Ja.
Post by Jens Lenge
(Ich kannte bislang immer nur "type Txxx = Tyyy;".)
Also mit "type TNewTyp = TVorhandenerTyp" wird lediglich
ein Typalias erzeugt, der zur Laufzeit wie TVorhandenerType
behandelt wird.
Post by Jens Lenge
a) type TMyType1 = Integer; // Geht
b) type TMyType2 = type Integer; // Geht auch
Richtig.
Post by Jens Lenge
Sind a) und b) synomyn/äquivalent?
Nein.

Mit b) wird ein _neuer Typ deklariert, nicht bloß ein Alias.
--
Arno
Sieghard Schicktanz
2012-10-23 19:05:53 UTC
Permalink
Hallo Arno,
Post by Arno Garrels
Post by Jens Lenge
a) type TMyType1 = Integer; // Geht
b) type TMyType2 = type Integer; // Geht auch
Richtig.
Post by Jens Lenge
Sind a) und b) synomyn/äquivalent?
Nein.
Mit b) wird ein _neuer Typ deklariert, nicht bloß ein Alias.
Hmmm, interessant, kannte ich bisher noch nicht. (Find's auch abwegig.)
b) erhebt für mich die Frage, ob damit "TMyType2" und "Integer" auch
richtigerweise inkompatibel sind? Sonst ist's doch bloß wieder ein Alias.
--
(Weitergabe von Adressdaten, Telefonnummern u.ä. ohne Zustimmung
nicht gestattet, ebenso Zusendung von Werbung oder ähnlichem)
-----------------------------------------------------------
Mit freundlichen Grüßen, S. Schicktanz
-----------------------------------------------------------
Matthias Hanft
2012-10-24 07:02:17 UTC
Permalink
Post by Sieghard Schicktanz
b) erhebt für mich die Frage, ob damit "TMyType2" und "Integer" auch
richtigerweise inkompatibel sind? Sonst ist's doch bloß wieder ein Alias.
Sind sie sicher nicht. In der Unit Controls wird seit jeher

type TDate = type TDateTime;

definiert, und beiden kann man beliebige reelle Zahlen zuweisen (und
auch als Funktionsparameter verwenden, wo *irgendwelche* Datums-/Zeit-
werte enthalten sind).

Gruß Matthias.
Sieghard Schicktanz
2012-10-24 20:37:15 UTC
Permalink
Hallo Matthias,
Post by Matthias Hanft
Sind sie sicher nicht. In der Unit Controls wird seit jeher
type TDate = type TDateTime;
definiert, und beiden kann man beliebige reelle Zahlen zuweisen (und
auch als Funktionsparameter verwenden, wo *irgendwelche* Datums-/Zeit-
werte enthalten sind).
Nagut - es gibt ja "gewisse" Kompatibilitätsrelationen zwischen den Typen.
Bloß sollte es irgendwie eine Definition oder Dokumentation geben, wie die
sich für solche Deklarationen auswirken.
--
(Weitergabe von Adressdaten, Telefonnummern u.ä. ohne Zustimmung
nicht gestattet, ebenso Zusendung von Werbung oder ähnlichem)
-----------------------------------------------------------
Mit freundlichen Grüßen, S. Schicktanz
-----------------------------------------------------------
Arno Garrels
2012-10-24 15:43:53 UTC
Permalink
Post by Sieghard Schicktanz
Hallo Arno,
Post by Arno Garrels
Post by Jens Lenge
a) type TMyType1 = Integer; // Geht
b) type TMyType2 = type Integer; // Geht auch
Richtig.
Post by Jens Lenge
Sind a) und b) synomyn/äquivalent?
Nein.
Mit b) wird ein _neuer Typ deklariert, nicht bloß ein Alias.
Hmmm, interessant, kannte ich bisher noch nicht. (Find's auch
abwegig.) b) erhebt für mich die Frage, ob damit "TMyType2" und
"Integer" auch richtigerweise inkompatibel sind? Sonst ist's doch
bloß wieder ein Alias.
Sie lassen sich zuweisen, bei Var-Parametern und z.B. bei published
Eventhandlern werden die Unterschiede deutlich.
--
Arno
Jens Lenge
2012-10-24 16:03:24 UTC
Permalink
Post by Arno Garrels
Sie lassen sich zuweisen, bei Var-Parametern und z.B. bei published
Eventhandlern werden die Unterschiede deutlich.
Leider gibt es dabei keine einheitliche Linie; z. B. bei Array-Typen
geht es munter durcheinander, siehe mein Posting "Typalias vs.
Typdefinition" nebenan.
Jens Lenge
2012-10-23 21:40:34 UTC
Permalink
Post by Arno Garrels
Post by Jens Lenge
Eine direkte Variablendeklaration
1.) var MyVar: AnsiString(850); // Fehler
2.) var MyVar: type AnsiString(850); // Auch Fehler
Warum sollte das auch funktionieren?
Naja, weil es mit fast allem anderen auch geht. ;)
Post by Arno Garrels
Eine Typdeklaration ist keine Variablendeklaration,
letztere erfordert die Angabe eines deklarierten Types
Nicht zwingend. Es ist "sonst" ohne weiteres möglich, die Typdefinition
(nicht bloß -deklaration) mit der Variablendeklaration zu vermengen:

var a: record ... end;

funktioniert auch ohne

type TMyRecord = record ... end;

Gleiches gilt für Arrays, Enums, sonstige Typen. Übrigens auch für
Strings: "var s: string[5];" ist auch ohne "type TString5 = string[5];"
erlaubt.
Post by Arno Garrels
warum sollte das also bei AnsiStrings anders sein?
Die Frage gebe ich zurück: Da es bei den anderen Typen erlaubt ist,
Typdefinition und Variablendeklaration zu vermengen, warum ist es dann
gerade bei "AnsiString(codepage)" *nicht* erlaubt?
Post by Arno Garrels
Also mit "type TNewTyp = TVorhandenerTyp" wird lediglich
ein Typalias erzeugt, der zur Laufzeit wie TVorhandenerType
behandelt wird. [...]
Danke für den Hinweis, mit den praktischen Auswirkungen des
Unterschiedes zwischen Typalias und neuer Typdefinition muss ich mich
nochmal intensiver beschäftigen. Ein paar Eigenheiten scheint es da
schon zu geben:

type
TIntAlias = Integer;
TIntType = type Integer;

TArrayAlias = array of Integer;
TArrayType = type TArrayAlias;

var
i1: Integer;
i2: TIntAlias;
i3: TIntType;

a1: array of Integer;
a2: TArrayAlias;
a3: TArrayType;

Bei i1 bis i3 klappen gegenseitige Zuweisungen in alle Richtungen, und
man kann i1/i2 austauschbar als "var i: Integer" oder "var i: TIntAlias"
an Funktionen übergeben.
Hingegen kann man weder i3 an solche Funktionen übergeben noch i1/i2 an
Funktionen, die "var i: TIntType" erwarten.
Genauso würde man (ich) das erwarten.

Bei den Arrays sieht es aber schon anders aus:
1.) "type TArrayType = type array of Integer;" wird mit einem Fehler
quittiert, "type TArrayType = type TArrayAlias;" hingegen klaglos
akzeptiert.
2.) Obwohl TArrayAlias "nur" ein Alias ist und kein neuer Typ, klappen
gegenseitige Zuweisungen zwischen a1 und a2 ebensowenig wie gegenüber a3.
3a) Man kann alle drei(!) Varianten als "var a: array of Integer" an
Funktionen übergeben (auch a3!).
3b) Man kann a1/a3 NICHT als "var a: TArrayAlias" übergeben (zumindest
a1 sollte aber doch eigentlich möglich sein, ist ja nur ein Alias).
3c) Man kann a1/a2 NICHT als "var a: TArrayType" übergeben (was
einleuchtet).
Arno Garrels
2012-10-24 06:02:08 UTC
Permalink
Post by Jens Lenge
Post by Arno Garrels
Post by Jens Lenge
Eine direkte Variablendeklaration
1.) var MyVar: AnsiString(850); // Fehler
2.) var MyVar: type AnsiString(850); // Auch Fehler
Warum sollte das auch funktionieren?
Naja, weil es mit fast allem anderen auch geht. ;)
Post by Arno Garrels
Eine Typdeklaration ist keine Variablendeklaration,
letztere erfordert die Angabe eines deklarierten Types
Nicht zwingend. Es ist "sonst" ohne weiteres möglich, die
Typdefinition (nicht bloß -deklaration) mit der Variablendeklaration
var a: record ... end;
funktioniert auch ohne
type TMyRecord = record ... end;
Gleiches gilt für Arrays, Enums, sonstige Typen.
Stimmt, Alzheimer lässt grüßen.
Post by Jens Lenge
Übrigens auch für
Strings: "var s: string[5];" ist auch ohne "type TString5 =
string[5];" erlaubt.
ShortString betrachte ich eher als eine Art dynamisches Array.
Post by Jens Lenge
Post by Arno Garrels
warum sollte das also bei AnsiStrings anders sein?
Da es bei den anderen Typen erlaubt ist,
Typdefinition und Variablendeklaration zu vermengen, warum ist es dann
gerade bei "AnsiString(codepage)" *nicht* erlaubt?
Möglicherweise Kompatibilitätsgründe? Im C++Builder ist AnsiString
eine Klasse:
/////////////////////////////////////////////////////////////////////////////
// AnsiStringT<CP> - C++ implementation of Delphi's AnsiString(CP) type
/////////////////////////////////////////////////////////////////////////////
template <unsigned short CP>
class RTL_DELPHIRETURN AnsiStringT : public AnsiStringBase
..
--
Arno
Jens Lenge
2012-10-24 12:20:27 UTC
Permalink
Post by Arno Garrels
Möglicherweise Kompatibilitätsgründe? Im C++Builder ist AnsiString
eine Klasse: [...]
In Delphi ist es ein "built-in type"; von daher sollte das keine Rolle
spielen.
Sieghard Schicktanz
2012-10-24 20:42:54 UTC
Permalink
Hallo Arno,
Post by Arno Garrels
ShortString betrachte ich eher als eine Art dynamisches Array.
Ein "ShortString" ist in keiner Weise als ein _dynamisches_ Array, der ist
ein ganz und gar _statisches_ Array.

Und damit ist er der einzige String-Typ, der zuverlässig und mit
vorhersehbarem Verhalten und Speicherbedarf in "embedded" Anwendungen
mit durchaus auch recht eingeschränkten Ressourcen verwendbar ist.
--
(Weitergabe von Adressdaten, Telefonnummern u.ä. ohne Zustimmung
nicht gestattet, ebenso Zusendung von Werbung oder ähnlichem)
-----------------------------------------------------------
Mit freundlichen Grüßen, S. Schicktanz
-----------------------------------------------------------
Hans-Peter Diettrich
2012-09-10 04:19:16 UTC
Permalink
Post by Jens Lenge
Hallo Welt, gemäß "Delphi in a Unicode World II" kann die Codepage von
AnsiStrings mittels "SetCodePage" beeinflusst werden; siehe
http://edn.embarcadero.com/article/38498#10SetCodePage
Mein real existierendes Delphi XE3 bietet "SetCodePage" aber
ausschließlich für RawByteStrings an. Irgendwie leuchtet mir die Logik
a) Ein AnsiString kann doch eigentlich viele verschiedene Codepages
haben. Wie kann ich beeinflussen, welche tatsächlich benutzt wird?
Bei der Deklaration der Stringvariablen, z.B. als AnsiString(0),
AnsiString(CP_UTF8).
Post by Jens Lenge
b) Ein RawByteString hat laut Doku die feste Codepage $FFFF als
Kennzeichen "keiner" Codepage. Wieso kann ich dann dennoch eine frei
gewählte Codepage setzen?
Weil er *keine feste* Codepage hat.

DoDi
Loading...