Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Array [Auszählungstyp] of irgendwas? (https://www.delphipraxis.net/178091-array-%5Bauszaehlungstyp%5D-irgendwas.html)

himitsu 17. Dez 2013 11:25

AW: Array [Auszählungstyp] of irgendwas?
 
@Mikkey: Der Delphi-Compiler bemängelt auch (an vielen Stellen) derartige Werte, welche sich außerhalb der Definition befinden,
allerdings "warnt" er da nur und läßt es dennoch zu und ich weiß jetzt nicht, in wie weit das beim ELSE zutrifft.


Hab das z.B. ausgenutzt, um eine Fremdkomponente um ein paar States zu erweitern.
Delphi-Quellcode:
const
  miImageMove = Succ(High(TIEMouseInteractVtItems));
  miImageZoom = Succ(miImageMove);
TIEMouseInteractVtItems ist ein Enum, welcher den Zustand der Input-Verarbeitung angibt
und bei dem hab ich zwei eigene Zustände angehängt, welche ich dann selber behandle.
(wobei ich mir diese Warnungen ausgeblendet hab >
Delphi-Quellcode:
{$WARNINGS OFF}
)

Enums und Sets besitzen leider keine Vererbung.



Und im Speicher sind nunmal auch die anderen Werte möglich.
Delphi-Quellcode:
type
  TMyEnum = (Anfang = 1, Mitte = 3, Ende = 5);
  TMySet = set of TMyEnum;
 
var
  MyEnum: TMyEnum;
  MySet: TMySet;
   
MySet := [TMyEnum.Anfang..TMyEnum.Ende]; // [Anfang..Ende];
for MyEnum in MySet do
  case MyEnum of
    Anfang: ShowMessage('Anfang');
    Mitte: ShowMessage('Mitte');
    Ende: ShowMessage('Ende');
    else ShowMessage(IntToStr(Ord(MyEnum)));
  end;
Delphi-Quellcode:
MySet := [TMyEnum.Anfang..TMyEnum.Ende]; // [Anfang..Ende];
Exclude(MySet, TMyEnum.Mitte);
if TMyEnum.Anfang in MyEnum then ; // hier mal mit dem Debugger nachsehn, was der als Inhalt für MyEnum angibt

Uwe Raabe 17. Dez 2013 11:35

AW: Array [Auszählungstyp] of irgendwas?
 
Zitat:

Zitat von Mikkey (Beitrag 1240090)
Delphi-Quellcode:
TEnum = (Anfang = 1, Mitte = 3, Ende = 5);
...
Gibt es eine saubere Methode, einen Typ aus drei Werten tatsächlich nur aus drei Werten bestehen zu lassen (und trotzdem eine selbstgewählte Numerierung beizubehalten)?

Man muss sich halt darüber in Klaren sein, daß man mit dem Zuweisen von Integerkonstanten bei der Deklaration der Enum-Werte eine Ordnungszahl definiert und nicht etwa einen willkürlichen Wert vergibt. Wenn man bei diesen Ordnungszahlen Lücken lässt, dann wird der Enum-Typ implizit um diese Lücken erweitert. Demnach sind solche Zuweisungen durchaus gültig:

Delphi-Quellcode:
type
  TEnum = (Anfang = 1, Mitte = 3, Ende = 5);
var
  pos: TEnum;
begin
  pos := TEnum(2);
  pos := TEnum(4);
end.

Zwar gibt es im Source dann keine Identifier mehr, die diese Werte darstellen, aber es sind immer noch gültige Werte für TEnum.

Sir Rufo 17. Dez 2013 18:37

AW: Array [Auszählungstyp] of irgendwas?
 
Und warum nicht so?
Delphi-Quellcode:
type
  TEnum = ( Anfang, Mitte, Ende );

const
  g_TEnumNames = Array[TEnum] of String = ( 'Anfang', 'Mitte', 'Ende' );

  // Wobei dieses nur in der Datenschicht deklariert werden muss, da es nur dort benötigt wird
  g_TEnumValues = array[TEnum] of integer = ( 1, 3, 5 );
Das hat auch den Vorteil, dass man auch unterschiedliche Datentöpfe mit unterschiedlichen Kennziffern (für die gleiche Aussage) haben kann, die im Programm aber komplett gleich behandelt werden.
Delphi-Quellcode:
unit LayerDataInhouse;

interface

  procedure Save( AEnum : TEnum );

implementation

  const
    C_TEnumValues : array[TEnum] of integer = ( 1, 3, 5 );

  procedure Save( AEnum : TEnum );
  begin
    Save( C_TEnumValues[AEnum] );
  end;

end.
und
Delphi-Quellcode:
unit LayerDataSomethingDifferent;

interface

  procedure Save( AEnum : TEnum );

implementation

  const
    C_TEnumValues : array[TEnum] of integer = ( 25, 3, 9 );

  procedure Save( AEnum : TEnum );
  begin
    Save( C_TEnumValues[AEnum] );
  end;

end.

Mikkey 17. Dez 2013 20:25

AW: Array [Auszählungstyp] of irgendwas?
 
@Sir Rufo:
Dass solche Verpackungsmöglichkeiten bestehen, ist schon klar. Es ging mir hauptsächlich um die Verwendung von Arrays per Aufzählungstyp.

@Himitsu:
Was ich meine ist so etwas:
Code:
{
  if (a<b)
    return a;
  else
    return b;
  return 0;
}
So etwas bringt beim C#-Compiler eine Warnung "line following 'return b;' is dead code". Tools zur Quelltextanalyse maulen noch weit mehr an, z.B. wenn Referenzen mit null, andere Daten mit ihrem Defaultwert initialisiert werden.


Mir macht aktuell aber noch etwas Anderes Probleme, der Code steht mir aktuell nicht zur Verfügung, aber ich gebe das mal sinngemäß wieder:

Delphi-Quellcode:
TEreignis = (EEins, EZwei, EDrei, EVier, EFuenf,ESechs, ESieben, EAcht, ENeun);
...
g_EreignisTypName: Array[TEreignisTyp] of String = (
  'the',
  'quick',
  'brown',
  'fox',
  'jumps'
  'over'
  'the',
  'lazy'
  'dog');
Greife ich nun im Code auf das Array mit den Werten des Typs zu, erhalte ich die falschen Einträge:
Delphi-Quellcode:
s1 := g_EreignisTypName[EAcht];
s2 := g_EreignisTypName[ENeun];
Dann steht in s1 'dog' und in s2 'lazy'. Tatsächlich sind lt. Debugger die Arraypositionen 6/7 und 8/9 vertauscht. Das gesamte Array wird im Tooltip aber in der richtigen Reihenfolge gezeigt.

Auch als Test zugewiesene Integer per 'EEins=1, EZwei=2, ..' haben nichts verändert.

Jemand eine Idee?

Sir Rufo 17. Dez 2013 20:50

AW: Array [Auszählungstyp] of irgendwas?
 
Zitat:

Zitat von Mikkey (Beitrag 1240143)
@Sir Rufo:
Dass solche Verpackungsmöglichkeiten bestehen, ist schon klar. Es ging mir hauptsächlich um die Verwendung von Arrays per Aufzählungstyp.

Da aber dieses
Delphi-Quellcode:
TEnum = ( Anfang = 1, Mitte = 3, Ende = 5);
ein paar Probleme mitbringt, ist es doch besser, diese Probleme von Anfang an zu vermeiden, als mühsam zu versuchen diese Probleme wieder auszubügeln.

Und dein Problem mit dem Enum kann ich so nicht nachvollziehen (funktioniert wie erwartet)
Delphi-Quellcode:
program dp_178091;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils,
  System.TypInfo;

type
  TEreignis = ( EEins, EZwei, EDrei, EVier, EFuenf, ESechs, ESieben, EAcht, ENeun );

const
  g_EreignisTypName : array [TEreignis] of string = ( 'the', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog' );

procedure Test;
  var
    LEreignis : TEreignis;
  begin
    for LEreignis := low( TEreignis ) to high( TEreignis ) do
      Writeln( Ord( LEreignis ), ' (', GetEnumName(TypeInfo(TEreignis),Integer(LEreignis)), ') - ', g_EreignisTypName[LEreignis] );
  end;

begin
  try
    Test;
  except
    on E : Exception do
      Writeln( E.ClassName, ': ', E.Message );
  end;

  ReadLn;

end.
liefert
Code:
0 (EEins) - the
1 (EZwei) - quick
2 (EDrei) - brown
3 (EVier) - fox
4 (EFuenf) - jumps
5 (ESechs) - over
6 (ESieben) - the
7 (EAcht) - lazy
8 (ENeun) - dog

Uwe Raabe 17. Dez 2013 21:05

AW: Array [Auszählungstyp] of irgendwas?
 
Zitat:

Zitat von Mikkey (Beitrag 1240143)
Dann steht in s1 'dog' und in s2 'lazy'. Tatsächlich sind lt. Debugger die Arraypositionen 6/7 und 8/9 vertauscht. Das gesamte Array wird im Tooltip aber in der richtigen Reihenfolge gezeigt.

Zeig mal den ganzen Code - da stimmt irgendetwas nicht.

Sir Rufo 17. Dez 2013 21:16

AW: Array [Auszählungstyp] of irgendwas?
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1240146)
Zitat:

Zitat von Mikkey (Beitrag 1240143)
Dann steht in s1 'dog' und in s2 'lazy'. Tatsächlich sind lt. Debugger die Arraypositionen 6/7 und 8/9 vertauscht. Das gesamte Array wird im Tooltip aber in der richtigen Reihenfolge gezeigt.

Zeig mal den ganzen Code - da stimmt irgendetwas nicht.

Es macht mich schon stutzig, dass da einmal
Delphi-Quellcode:
TEreignis
deklariert wird und dann
Delphi-Quellcode:
array[TEreignisTyp]
... ok, die strings in der array definition sind so auch nicht syntaktisch korrekt ...

Ich liebe diese "... so ähnlich, ungefähr, nun ja, ist es es und das tut nicht ..."

jaenicke 17. Dez 2013 22:17

AW: Array [Auszählungstyp] of irgendwas?
 
Zitat:

Zitat von Mikkey (Beitrag 1240143)
Dann steht in s1 'dog' und in s2 'lazy'. Tatsächlich sind lt. Debugger die Arraypositionen 6/7 und 8/9 vertauscht. Das gesamte Array wird im Tooltip aber in der richtigen Reihenfolge gezeigt.

Hast du auch die Optimierung unter Compiler in den Projektoptionen deaktiviert, wenn du debuggen möchtest? ;-)

himitsu 18. Dez 2013 01:30

AW: Array [Auszählungstyp] of irgendwas?
 
Zitat:

Zitat von Mikkey (Beitrag 1240143)
Code:
{
  if (a<b)
    return a;
  else
    return b;
  return 0;
}

Im C springt der beim Return raus, was dem heutigen
Delphi-Quellcode:
Exit(Result);
entspricht
Delphi-Quellcode:
begin
  if a < b then
    Exit(a)
  else
    Exit(b);
  Exit(0);
end;
Delphi-Quellcode:
begin
  if a < b then begin
    Result := a;
    Exit;
  end else begin
    Result := b;
    Exit;
  end;
  Result := 0;
end;
Ob hier Delphi meint, daß
Delphi-Quellcode:
Exit(0);
nicht verwendet wird, weiß ich nicht, aber eventuell ja z.B. nach einem
Delphi-Quellcode:
Raise
das auch bemängelt wird.
Bei dem
Delphi-Quellcode:
Result := 0;
wird jedenfalls (glaub ich) gewarnt, daß es nicht verwendet wird.

Beim Nächsten wird dagegen definitiv bemängelt, daß
Delphi-Quellcode:
Result := a
und
Delphi-Quellcode:
Result := b
nicht verwendet werden.
Delphi-Quellcode:
begin
  if a < b then
    Result := a
  else
    Result := b;
  Result := 0;
end;
Es gibt eigentlich schon recht viele Warnungen, welcher der Compiler wirft, vorallem an vielen Stellen, wo Variablen zugewiesen, aber deren Wert nicht verwendet wird, da später ein anderer Wert zugewiesen, aber zwischendurch Dieser nicht mehr ausgelesen/verwendet wird.
Genauso wie an fast allen Stellen die "nicht initialisiert" Warnung kommt. (abgesehn von ein paar kleinen gemeinen, aber seltenen Fällen, mit Strings und Interfaces)

Mikkey 18. Dez 2013 07:12

AW: Array [Auszählungstyp] of irgendwas?
 
Es tut mir leid, dass ich doch keine spannende Geschichte gefunden habe :oops:

Der Fehler Ereignis/EreignisTyp lag natürlich am aus-dem-Gedächtnis-hinschreiben.

Zunächst mal habe ich gestern nicht richtig hingeschaut, das Array hatte auch im Tooltip die falsche Reihenfolge.

Dann hatte ich vorher tatsächlich in der Definition die Einträge 6/7 und 8/9 im Array g_EreignisTypName vertauscht gehabt, aber danach korrigiert. Allerdings hatte ich in der Version den Export der Text-Lokalisierung (dafür sind die Nummern erforderlich) laufen lassen. Damit stand 'dog' unter 13 und 'lazy' unter 14.

In der Folge hat er natürlich bei jedem Test die falsche Belegung wieder eingelesen und damit den eigentlich korrigierten Fehler wiederhergestellt. :wall:

Nach erneutem Export bringt er die richtigen Texte heraus.

Vielen Dank nochmal.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:56 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz