![]() |
AW: Eure Meinung: Syntaxerweiterung Set-Typen auf mehr als 255 Elemente
Zitat:
Gut,
Delphi-Quellcode:
(2-4 Byte) hat weniger Bytes, als irgendwas in der Richtung
BT EDX, AL
Delphi-Quellcode:
(
TEST LONG PTR EDX + [EAX shr 5], EAX and $1F
Delphi-Quellcode:
20+ Bytes), aber schneller ist es dennoch meistens nicht.
if LongBool(A[i shr 5] and (i and $1F)) then
OK, ein volles 256er-ENUM ist auch nur 32 Byte groß und nur weniger wollen statische Arrays mit bis zu 0,5 GB auf dem Stack haben, welche bis 4 Milliarden Werte enthalten dürfen :angle: |
AW: Eure Meinung: Syntaxerweiterung Set-Typen auf mehr als 255 Elemente
Hallo Delphifreunde, vor einem ähnlichen Problem (bei Delphi 7) stehe ich seit längerem auch. Zwar mag es für Aufzählungstypen keine Anzahlsbegrenzung auf 256 zu geben, der "in"-Befehl scheitert aber ab dem 257. Element. Folgender Beispielcode mit einer Aufzählungsmenge mit 257 Elementen:
Delphi-Quellcode:
Bis zur viertletzten Codezeile compiliert er, bei der drittletzten Codezeile jedoch, beim Zugriff auf das 257. Element, moniert der Compiler: "Konstantenausdruck verletzt untere Grenzen" (hä, untere??).
procedure TForm1.FormCreate(Sender: TObject);
type TMenge = ( m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16, m17, m18, m19, m20, m21, m22, m23, m24, m25, m26, m27, m28, m29, m30, m31, m32, m33, m34, m35, m36, m37, m38, m39, m40, m41, m42, m43, m44, m45, m46, m47, m48, m49, m50, m51, m52, m53, m54, m55, m56, m57, m58, m59, m60, m61, m62, m63, m64, m65, m66, m67, m68, m69, m70, m71, m72, m73, m74, m75, m76, m77, m78, m79, m80, m81, m82, m83, m84, m85, m86, m87, m88, m89, m90, m91, m92, m93, m94, m95, m96, m97, m98, m99, m100, m101, m102, m103, m104, m105, m106, m107, m108, m109, m110, m111, m112, m113, m114, m115, m116, m117, m118, m119, m120, m121, m122, m123, m124, m125, m126, m127, m128, m129, m130, m131, m132, m133, m134, m135, m136, m137, m138, m139, m140, m141, m142, m143, m144, m145, m146, m147, m148, m149, m150, m151, m152, m153, m154, m155, m156, m157, m158, m159, m160, m161, m162, m163, m164, m165, m166, m167, m168, m169, m170, m171, m172, m173, m174, m175, m176, m177, m178, m179, m180, m181, m182, m183, m184, m185, m186, m187, m188, m189, m190, m191, m192, m193, m194, m195, m196, m197, m198, m199, m200, m201, m202, m203, m204, m205, m206, m207, m208, m209, m210, m211, m212, m213, m214, m215, m216, m217, m218, m219, m220, m221, m222, m223, m224, m225, m226, m227, m228, m229, m230, m231, m232, m233, m234, m235, m236, m237, m238, m239, m240, m241, m242, m243, m244, m245, m246, m247, m248, m249, m250, m251, m252, m253, m254, m255, m256); var Menge: TMenge; begin if Menge in [m255] then beep; if Menge in [m256] then beep;//hier Compilerfehler! end; end. Woran liegt das, und hat man eine Chance, das wegzubekommen? Mit {$Z2} oder {$Z4} war ich auch nicht erfolgreich. Danke und Gruß Delphi-Laie |
AW: Eure Meinung: Syntaxerweiterung Set-Typen auf mehr als 255 Elemente
Mit dem Konstukt [m256] wird vom Compiler ein Set erzeugt, was wegen der bekannten Beschränkung eben nicht geht. Das kriegst du auch nicht weg - zumindest nicht mit Sets.
|
AW: Eure Meinung: Syntaxerweiterung Set-Typen auf mehr als 255 Elemente
OK, danke! Nun bin ich allerdings völlig verwirrt.
Da wurde doch eine Aufzählungsmenge und eben kein Set deklariert! Jedenfalls wurde das Schlüsselwort "set" doch gar nicht verwendet. Nicht zuletzt, Du warst es, der früher in dieser Diskussion schon schrieb: Zitat:
|
AW: Eure Meinung: Syntaxerweiterung Set-Typen auf mehr als 255 Elemente
Doch, denn das nach dem IN ist ein SET.
TMenge kann intern Byte, Word oder LongWord sein, also bis 4 Millarden Werte enthalten, aber als SET ist hier maximal Byte-ENUM erlaubt. (bis 256 Werte aka Bits = 32 Byte) Man kann über eine Funktion das Set durch ein Array ersetzen, am Besten als OpenArray, um hier auch die direkte Angabe zu unterstützen.
Delphi-Quellcode:
In neuren Delphis könnte man auf die Idee kommen das als ClassOperator zu bauen, aber leider verfällt Delphi immer beim [...] auf EMUM zurück und prüft erst dann ob es einen Operator gibt. :wall:
if ContainsMenge(Menge, [m256]) then ;
function ContainsMenge(Value: TMenge, List: array of TMenge): Boolean; |
AW: Eure Meinung: Syntaxerweiterung Set-Typen auf mehr als 255 Elemente
Zitat:
Zitat:
Delphi-Quellcode:
var
I: Integer; begin if I in [256] then; |
AW: Eure Meinung: Syntaxerweiterung Set-Typen auf mehr als 255 Elemente
Ach ja, {$Zx} bzw. {$MINENUMSIZE x} definiert nur die Mindestgröße (MinEnumSize) und das leider auch nur vom ENUM und nicht vom SET.
Hast du ein ENUM mit nur 3 Werten, dann ist es standardmäßig 1 Byte groß. Aber in C++ bzw. der WinAPI sind ENUMs gern ganze ein INT, was man im Delphi z.B. mit $Z4 erreichen könnte. |
AW: Eure Meinung: Syntaxerweiterung Set-Typen auf mehr als 255 Elemente
Danke Euch beiden mit Eurer Geduld!
Dann ist es eben auch ohne das Schlüsselwort "set" ein Set, jedenfalls bei der Verwendung mit "in", und dann ist es auch nachvollziehbar, warum der Zugriff scheitert. Der scheitert aber nur (?) mit dem Schlüsselwort "in". Hingegen wird z.B.
Delphi-Quellcode:
showmessage(inttostr(ord(m256)))
anstandslos compiliert und auch ausgeführt, zeigt dann richtigerweise "256" an. |
AW: Eure Meinung: Syntaxerweiterung Set-Typen auf mehr als 255 Elemente
Weil das kein SET ist.
Beim [OrdinalerTyp] oder [OrdinalerTyp, ...] wird nunmal implizit ein SET aus deinem ENUM generiert. Schön wäre es, wenn ab einer gewissen Größe hier stattdessen das als ARRAY generiert würde (aber das geht leider "noch" nicht), bzw. auch bei Weniger ARRAY unterstützt wird, bei der Suche nach kompatiblen Funktionen. Mit ORD wird nur der Wert des ENUMs in einen anderen ordinalen Typen "Integer" konvertiert. (das ist wie beim
Delphi-Quellcode:
)
Integer(EinPointer)
Delphi-Quellcode:
ShowMessage(IntToStr(Word(m256))); // weil der ENUM 9 bis 16 Bit groß ist ... bei $Z4 LongWord(m256) weil 32 Bit, bzw. 4 Byte
|
AW: Eure Meinung: Syntaxerweiterung Set-Typen auf mehr als 255 Elemente
Mir ist bewusst dass der Fragende sich hier auf D7 bezog. Dennoch:
Nennt mich Ketzer aber ich löse das bei neueren Delphis inzwischen in etwa so (aus dem Gedächtnis, da kein Delphi zur Hand, deshalb als Pseudocode betrachten)
Delphi-Quellcode:
Die Performance kommt mit Sicherheit nicht an set of heran, kommt daher auf den Einzelfall an. In meinem Fall sind die implicit-Operatoren deutlich umfangreicher, weshalb die Prüfung auf Eindeutigkeit wichtig ist.
type
PBigSetOf = ^TBigSetOf; // Ich arbeite meist mit Zeigern um Speicherkuddelmuddel zu vermeiden TBigSetOf = record FElements: TArray<word>; class operator implicit(A: TBigSetOf): TArray<word>; class operator implicit(A: TArray<word>): TBigSetOf; class operator in(A: Word, B: TBigSetOf): Boolean; end; implementation const // Für die Erzeugung der Konstanten habe ich mir ein kleines Tool geschrieben m0 = 0; {...} m1024 = 1024; class operator implicit(A: TBigSetOf): TArray<word>; begin Self.FElements := A.FElements: Result := Self.FElements; end; class operator implicit(A: TArray<word>): TBigSetOf; var LElement: Word; begin for LElement in A do begin if not LElement in Self then begin Self.FElements := Self.FElements + [LElement]; end else begin raise // Irgendwas wegen nicht eindeutig // deswegen auch der Umweg über einen Record // anstatt einfach nur ein array of Word zu benutzen end; end; Result := Self; end; class operator in(A: Word, B: TBigSetOf): Boolean; var LElement: Word; begin Result := False; for LElement in B.FElements do begin if LElement = A then begin Result := True; Break; end; end; end; procedure Test; var LBigSetOf: TBigSetOf; begin LBigSetOf := [m0, m128, m256, m512, m1024]; if m96 in LBigSetOf then begin // Nein end else if m512 in LBigSetOf then begin // Ja end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:33 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz