Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt" (https://www.delphipraxis.net/180596-hinweis-unterdruecken-auf-x-zugewiesener-wert-wird-niemals-benutzt.html)

Gloegg_FHBI 2. Jun 2014 08:39

Delphi-Version: 7

Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Hallo DPler,

Ich habe folgende Klasse geschrieben:
Delphi-Quellcode:
type
  IWaitCursor = interface
  end;

  TWaitCursor = class (TInterfacedObject, IWaitCursor)
  private
    fCursor : TCursor;
  public
    constructor Create;
    destructor Destroy; override;
  end;

implementation

constructor TWaitCursor.Create;
begin
  inherited;
  fCursor := Screen.Cursor;
  Screen.Cursor := crHourGlass;
  MainFrom.TrafficLight := tlRed;
end;

destructor TWaitCursor.Destroy;
begin
  Screen.Cursor := fCursor;
  MainFrom.TrafficLight := tlGreen;
  inherited;
end;
Diese Klasse benutze ich um in länger dauernden Prozeduren den Wartecursor anzuzeigen und automatisch den richtigen Cursor wiederherzustellen, nachdem die Prozedur beendet ist.

Nun bekomme ich aber für jede Verwendung einen Hinweis vom Compiler, dass die variable nicht genutzt wird. Kann man das irgendwie für diese Fälle ausschalten?

Delphi-Quellcode:
procedure TMainForm.MyMethod;
var
  cur : IWaitCursor;
begin
  cur := TWaitCursor.Create; // Auf 'cur' zugewiesener Wert wird niemals benutzt
  sleep(1000);
end;

mkinzler 2. Jun 2014 08:42

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
In diesem Fall könnte man ausnahmsweise with verwenden:
Delphi-Quellcode:
with TWaitCursor.Create do
  sleep(1000);

Neutral General 2. Jun 2014 08:52

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Zitat:

Zitat von mkinzler (Beitrag 1260981)
In diesem Fall könnte man ausnahmsweise with verwenden:
Delphi-Quellcode:
with TWaitCursor.Create do
  sleep(1000);

Muss er ja nicht einmal.

Delphi-Quellcode:
procedure TMainForm.MyMethod;
begin
  TWaitCursor.Create;
  sleep(1000);
end;
Geht auch und produziert keine Warnung. Warum eine Variable anlegen wenn man sie eh nicht verwendet?

Sir Rufo 2. Jun 2014 08:54

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Zitat:

Zitat von mkinzler (Beitrag 1260981)
In diesem Fall könnte man ausnahmsweise with verwenden:
Delphi-Quellcode:
with TWaitCursor.Create do
  sleep(1000);

Das gibt ein Speicherleck ;)

Zitat:

Zitat von Neutral General (Beitrag 1260982)
Zitat:

Zitat von mkinzler (Beitrag 1260981)
In diesem Fall könnte man ausnahmsweise with verwenden:
Delphi-Quellcode:
with TWaitCursor.Create do
  sleep(1000);

Muss er ja nicht einmal.

Delphi-Quellcode:
procedure TMainForm.MyMethod;
begin
  TWaitCursor.Create;
  sleep(1000);
end;
Geht auch und produziert keine Warnung. Warum eine Variable anlegen wenn man sie eh nicht verwendet?

Aber ebenfalls ein Speicherleck ;)

Neutral General 2. Jun 2014 08:59

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Stimmt. Dann halt mit Variable und try-finally :mrgreen:

Sir Rufo 2. Jun 2014 09:00

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Erweitere die Klasse um eine
Delphi-Quellcode:
class function Construct : IWaitCursor;
Delphi-Quellcode:
type
  IWaitCursor = interface
  end;

  TWaitCursor = class (TInterfacedObject, IWaitCursor)
  private
    fCursor : TCursor;
  public
    constructor Create;
    destructor Destroy; override;

    class function Construct : IWaitCursor;
  end;

implementation

class function TWaitCursor.Construct : IWaitCursor;
begin
  Result := TWaitCursor.Create;
end;

constructor TWaitCursor.Create;
begin
  inherited;
  fCursor := Screen.Cursor;
  Screen.Cursor := crHourGlass;
  MainFrom.TrafficLight := tlRed;
end;

destructor TWaitCursor.Destroy;
begin
  Screen.Cursor := fCursor;
  MainFrom.TrafficLight := tlGreen;
  inherited;
end;
dann kann das ohne Speicherleck und Warnung so benutzt werden
Delphi-Quellcode:
procedure Foo;
begin
  TWaitCursor.Construct;
  Sleep( 1000 );
end;
Zitat:

Zitat von Neutral General (Beitrag 1260984)
Stimmt. Dann halt mit Variable und try-finally :mrgreen:

Wieso? ;)

Sir Rufo 2. Jun 2014 09:05

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Nebenbei bemerkt, ist diese direkte Referenzierung
Delphi-Quellcode:
MainFrom.TrafficLight := tlRed;
natürlich sehr suboptimal. Damit hast du der Klasse eine sehr starke Abhängigkeit gegeben, die man eigentlich vermeiden soll (eigentlich muss).

Das solltest du anders lösen

Sir Rufo 2. Jun 2014 09:40

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Hier eine Variante ohne diese Abhängigkeiten und Überflüssiges (z.B.
Delphi-Quellcode:
IWaitCursor
) und vor allem auch kaskadierbar
Delphi-Quellcode:
unit WaitCursor;

interface

uses
  System.SysUtils,
  Vcl.Forms,
  Vcl.Controls;

type
  TWaitCursor = class( TInterfacedObject )
  private
    class var [weak] _Instance : TWaitCursor;
    class var _OnShow : TProc;
    class var _OnHide : TProc;
  private
    FCursor : TCursor;
  protected
    constructor Create;
  public
    destructor Destroy; override;

    class function Show : IInterface;
    class property OnShow : TProc read _OnShow write _OnShow;
    class property OnHide : TProc read _OnHide write _OnHide;
  end;

implementation

{ TWaitCursor }

constructor TWaitCursor.Create;
begin
  inherited;
  FCursor := Screen.Cursor;
  Screen.Cursor := crHourGlass;
  if Assigned( _OnShow )
  then
    _OnShow( );
end;

destructor TWaitCursor.Destroy;
begin
  _Instance := nil;
  Screen.Cursor := FCursor;
  if Assigned( _OnHide )
  then
    _OnHide( );
  inherited;
end;

class function TWaitCursor.Show : IInterface;
begin
  if not Assigned( _Instance )
  then
    _Instance := TWaitCursor.Create;
  Result := _Instance;
end;

end.
Beispiel
Delphi-Quellcode:
procedure Foo;
begin
  TWaitCursor.Show;
  Sleep( 1000 );
end;

procedure Bar;
begin
  TWaitCursor.Show;
  Foo;
end;

himitsu 2. Jun 2014 09:44

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Ja, man kann solche Meldungen deaktivieren, aber mann kann den "Fehler" auch einfach beseitigen. :angel2:

Und am Einfachsten ist es, wenn man die ungenutzte Variable weglässt.
Oder man macht z.B. ein
Delphi-Quellcode:
if cur = nil then ;
dahinter und nutzt die Variable.


Ach ja, die Variable weglassen und den Resultwert "ignorieren" geht nur, wenn diese Funktion nicht deaktiviert ist.
Wobei das eigentlich nicht mehr vorkommen sollte, da es nur ein Kompilerschalter für die Unterstüzung von uraltem Code ist. (Abwärtzkompatibilität)
siehe
Delphi-Quellcode:
{$X+}
/
Delphi-Quellcode:
{$EXTENDEDSYNTAX ON}


Und hier gibt es noch das Problem der impliziten Typumwandlung.
Da man hier ja unbedingt das Interface braucht, müsste man ohne die Variable den Typ manuell in ein Interface umwandeln.
Delphi legt bei Zwischenergebnissen und für nicht verwendete Result-Werte eine lokale Variable an, wobei es hier allerdings den Klassentyp verwendet und nicht das Interface.

Also ich hätte da eine Class-Funktion in TWaitCursor eingebaut, welche das Interface als result liefert, womit man sich die manuellen umwandlungen überall erspart und das nur an einer Stelle macht.
[edit] siehe das Beispiel vor mir.

Union 2. Jun 2014 09:50

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Im OP steht doch was von Delphi 7. Gab's da schon class vars, functions und properties?

Sir Rufo 2. Jun 2014 09:52

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Zitat:

Zitat von Union (Beitrag 1260989)
Im OP steht doch was von Delphi 7. Gab's da schon class vars, functions und properties?

Im Profil des TE steht was von XE2 (dafür habe ich mich entschieden ;))

himitsu 2. Jun 2014 09:56

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Selbst wenn D7:
- Class-Functions gab es definitiv schon
- Class-Var bin ich nicht mehr sicher, aber ich glaub schon und wenn doch nicht, dann kann man das auch anders lösen (z.B. globale Variable in der Implementation)

Gab es nicht ein Feature-Request von mir, wo ich mir wünschte, daß dieses standardmäßig mit dem Delphi aus dem Profil gefüllt wird, oder wo standardmäßig "nichts" da ausgewählt ist?

Der schöne Günther 2. Jun 2014 10:08

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Weniger zur Technik, sondern zur Philosophie:

Zitat:

Zitat von Sir Rufo (Beitrag 1260987)
Hier eine Variante ohne diese Abhängigkeiten und Überflüssiges (z.B.
Delphi-Quellcode:
IWaitCursor
) und vor allem auch kaskadierbar

Kritik soll es nicht sein (ist ja technisch einwandfrei, Daumen hoch auf für das
Delphi-Quellcode:
[weak]
!), aber ich finde grade bei Dingen wie etwas, das in seinem Konstruktor und Destruktor aktiv das Gesamtbild des Systems verändert es nicht angebracht, das automatisch ablaufen zu lassen wenn es out of scope geht.

Habe ich ein
Delphi-Quellcode:
procedure aufwändigeAufgabe();
begin
   // Schritt 1
   TWaitCursor.Show();
   doStuff();
   doEvenMoreStuff();
   
   // Schritt 2
   transferMoney();
   logStuff();
end;
und jemand spaltet mir das, ohne es besser zu wissen in
Delphi-Quellcode:
procedure aufwändigeAufgabe();
begin
   schritt1();
   schritt2();
end;

procedure schritt1();
begin
   TWaitCursor.Show();
   doStuff();
   doEvenMoreStuff();
end;

[...]
auf, ist das Stundenglas nur noch für Schritt 1 zu sehen. Ja, hätte Refactor-Man es richtig gemacht, hätte er es in
Delphi-Quellcode:
aufwändigeAufgabe()
gelassen. Aber ich finde den Fehler kann man zu einfach machen.


Ich packe gerne Dinge wie eine lokale
Delphi-Quellcode:
TStringList
in eine interface-referenzierte Tonne um mir den try..finally-Block für das Aufräumen zu sparen, aber grade im Fall mit dem Cursor wäre mein persönlicher Geschmack wirklich weiterhin ein waschechter try..finally-Block. Da sieht man auch auf den ersten Blick was man hat- Ohne zu wissen, was sich hinter den
Delphi-Quellcode:
TWaitCursor
-Kulissen abspielt.

Dejan Vu 2. Jun 2014 10:14

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Unabhängig davon könnte man dem TE -da die Frage schon beantwortet wurde- den Tipp geben, hier keine Klasse zu erzeugen, sondern eher einen kleinen UI-Controller, der das übernimmt. Da Delphi das Paradigma 'Wer Dreck macht, muss aufräumen' vorgibt (Create/Free, Begin/EndUpdate usw.) sollte man das imho hier auch bewusst so umsetzen:
Delphi-Quellcode:
...
  UIController.BeginWaitCursor;
  Try
    DoFoo();
    DoBar();
    UIController.BeginSQLWaitCursor;
    Try
      DoDatabaseStuff();
    Finally
      UIController.EndWaitCursor;
    End;
    DoEvenMoreStuff();
  Finally
    UIController.EndWaitCursor;
  End;
...
Und wenn Refactor-Man jetzt loslegt, muss er ja die Try-Finally-Blöcke zusammen lassen.

Es dürfte in aktuellen Delphis auch mit Lambda-Ausdrücken gehen...

Delphi-Quellcode:
Procedure WaitCursor (a : Action); // Oder wie das auch immer deklariert wird
begin
  oldCursor := Screen.Cursor;
  Screen.Cursor := clWait;
  try
    Action();
  finally
    Screen.Cursor := oldCursor;
  End
End;
Da jetzt gerade ein Interface zu verwenden, erscheint mir etwas unglücklich.

Sir Rufo 2. Jun 2014 10:25

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
@Dejan Vu

Wenn es danach geht, muss man die gesamte Vorgehensweise in Frage stellen.

Denn Sinn macht das hier nur, wenn der echte Code in einem Thread gestartet wird (oder - igitt - mit
Delphi-Quellcode:
Application.ProcessMessages
rumhantiert wird), ansonsten sieht man davon eher recht wenig (z.B. das Setzen des TrafficLights im Ausgangsbeitrag), da der MainThread blockiert ist.

Wenn das aber in einem Thread erfolgt, dann wird der Cursor viel zu früh wieder zurück gesetzt.

p80286 2. Jun 2014 11:11

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Hallo zusammen,

mir ist schon des öfteren mal eine Konstruktion wie

Delphi-Quellcode:
Myclass.Create;
Myclass.Machwas;
über den Weg gelaufen.

Meiner Meinung nach richtig wäre
Delphi-Quellcode:
Wert:=Myclass.Create;
Wert.Machwas;
Wert.Free;
Da erstere Version auch funktioniert (?) könntet Ihr mich einmal aufklären was dahinter steckt?

Gruß
K-H

mkinzler 2. Jun 2014 11:20

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Es ist ein Konstruktoraufruf ohne das die zurückgegeben Referenz in einer Variable gespeichert wird

himitsu 2. Jun 2014 11:27

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Zitat:

Delphi-Quellcode:
Myclass.xxx

Du meinst doch bestimmt TMyClass?

Nja, das ist im Prinzip ein
Delphi-Quellcode:
procedure ShowWaitCursor;
(ohne Klasse), nur daß man den Code aufgeräumt hat und es in der zugehörigen Klasse positionierte.


Und nur weil man es ohne explizite Referenz nutzen kann
Delphi-Quellcode:
begin
  TWaitCursor.Show; // oder als einfache Funktion "ShowWaitCursor;"
  ...
end;
verbietet es keiner, wenn man in Sonderfällen dennoch eine Referenz verwendet.

z.B.:
Delphi-Quellcode:
begin
  X := TWaitCursor.Show;
  try
    ...
  finally
    X := nil; // oder X.Hide;
  end;
  ...
end;

mkinzler 2. Jun 2014 11:30

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Falls ohne T, dann wird der Konstruktor einfach als normle Methode auf eine viorhandene Instanz angewendet.

Sir Rufo 2. Jun 2014 11:33

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Wenn
Delphi-Quellcode:
MyClass
ein Klassentyp ist und dann muss
Delphi-Quellcode:
MyClass.MachWas
eine
Delphi-Quellcode:
class procedure
sein.

Daraus folgt weiterhin, dass mit
Delphi-Quellcode:
MyClass.Create;
ein Speicherleck erzeugt wird.

Wenn
Delphi-Quellcode:
MyClass : TMyClass;
ist (Instanz-Variable), dann wird mit
Delphi-Quellcode:
MyClass.Create;
der
Delphi-Quellcode:
constructor
nochmals durchlaufen ohne eine weitere Instanz zu erzeugen. Dazu muss aber
Delphi-Quellcode:
MyClass
schon mit einer gültigen Instanz belegt sein.

So aus dem Kontext herausgerissen, kann man dazu also herzlich wenig sagen, ausser im Nebel herumstochern.
Zitat:

Zitat von mkinzler (Beitrag 1261009)
Falls ohne T, dann wird der Konstruktor einfach als normle Methode auf eine viorhandene Instanz angewendet.

Das T ist nicht zwingend vorgeschrieben, aber sehr empfehlenswert

Gloegg_FHBI 2. Jun 2014 11:43

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Wow, da ist man mal für drei kurze Stunden nicht in der DP und schon hat man nen Haufen antworten.

@SirRufo
Die Lösung mit dem Construct ist schonmal sehr gut, das werde ich auf jeden Fall so machen. Da ich bei diesem Projekt noch mit Delphi 7 arbeiten muss, kann ich leider keine [Attribute] und anonymen Methoden verwenden, dass entkoppeln werde ich also anders machen müssen.

Danke an alle.

Sir Rufo 2. Jun 2014 11:47

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Zitat:

Zitat von Gloegg_FHBI (Beitrag 1261013)
Wow, da ist man mal für drei kurze Stunden nicht in der DP und schon hat man nen Haufen antworten.

@SirRufo
Die Lösung mit dem Construct ist schonmal sehr gut, das werde ich auf jeden Fall so machen. Da ich bei diesem Projekt noch mit Delphi 7 arbeiten muss, kann ich leider keine [Attribute] und anonymen Methoden verwenden, dass entkoppeln werde ich also anders machen müssen.

Danke an alle.

Das
Delphi-Quellcode:
[weak]
wird nur für ARC Compiler benötigt, kannst du also mit Compilerschaltern ausklammern.

Anstatt der anonymen Methoden nimmst du einfach
Delphi-Quellcode:
TMethod = procedure of object;
.

himitsu 2. Jun 2014 11:52

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Das
Delphi-Quellcode:
[weak]
-Attribut ist aber sowieso in allen Compilern implementiert.
Mann kann es also problemlos überall angeben, auch wenn es nicht überall ausgewertet/beachtet wird.

Auch wenn es "aktuell" nur von den mobilen Compilern ausgewertet wird, hab ich das dennoch bei einem aktuellen Projekt überall mit angegeben.
Indirekt hat man so auch eine Dokumentationen der nichtgezählten Referenzen.

p80286 4. Jun 2014 13:09

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Zitat:

Zitat von Sir Rufo (Beitrag 1261011)
Wenn
Delphi-Quellcode:
MyClass
ein Klassentyp ist und dann muss
Delphi-Quellcode:
MyClass.MachWas
eine
Delphi-Quellcode:
class procedure
sein.

Daraus folgt weiterhin, dass mit
Delphi-Quellcode:
MyClass.Create;
ein Speicherleck erzeugt wird.

Wenn
Delphi-Quellcode:
MyClass : TMyClass;
ist (Instanz-Variable), dann wird mit
Delphi-Quellcode:
MyClass.Create;
der
Delphi-Quellcode:
constructor
nochmals durchlaufen ohne eine weitere Instanz zu erzeugen. Dazu muss aber
Delphi-Quellcode:
MyClass
schon mit einer gültigen Instanz belegt sein.

So aus dem Kontext herausgerissen, kann man dazu also herzlich wenig sagen, ausser im Nebel herumstochern.
Zitat:

Zitat von mkinzler (Beitrag 1261009)
Falls ohne T, dann wird der Konstruktor einfach als normle Methode auf eine viorhandene Instanz angewendet.

Das T ist nicht zwingend vorgeschrieben, aber sehr empfehlenswert

Pardon, das T hatte ich geschlabbert, aber jetzt hab ich wenigstens ein paar Ansatzpunkte unter denen ich weiter suchen kann.

vielen Dank

K-H

hoika 4. Jun 2014 14:19

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Hallo,

was mich interessieren würde:

Gibt es keinen Compilerschalter, um genau diese Warnung zu unterdrücken ?


Heiko

himitsu 4. Jun 2014 14:25

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Doch, aber besser wäre es die Fehler wegzumachen, da man sonst neue Fehler nicht mehr sieht.

Delphi-Quellcode:
{$WARN ...}

DeddyH 4. Jun 2014 14:27

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Soweit ich weiß, kann man zwar Warnungen gezielt abschalten, Hinweise aber nur global.

himitsu 4. Jun 2014 16:26

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Laut OH ist es lokal.
Das wäre also von da wo man es deaktiviert weg, bis dahin man es wieder aktiviert und auch nur in der aktuellen Unit.

(Außer man kann sowas in den Projektoptionen nochmals angeben, was dann aber nur den Defaultwert ändert, welcher bei Begin jeder Unit gilt)

DeddyH 4. Jun 2014 17:09

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Was ich meinte: man kann ganz bestimmte Warnungen abschalten (z.B. SYMBOL_PLATFORM), bei Hinweisen aber nur alle oder keine.

himitsu 4. Jun 2014 18:28

AW: Hinweis unterdrücken "Auf x zugewiesener Wert wird niemals benutzt"
 
Aso, joar, das stimmt leider.


z.B. warum bekommt ich "platform"-Warnungen, für Nur-Windows-Code, wenn ich in der VCL arbeite ... da gibt es nur Windows und somit sind diese Warnungen nuztlos.
Oder vom Debugger kann man bestimmte Exceptions ignorieren, aber ich würder da gern auch abhängig von der Message oder der Auslösecodestelle (Unit) bestimmte Exceptions ignorieren können und nicht gleich alle dieses Typs.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:22 Uhr.

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