Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Variablen nicht NIL 64Bit (https://www.delphipraxis.net/197748-variablen-nicht-nil-64bit.html)

EWeiss 1. Sep 2018 08:45

Variablen nicht NIL 64Bit
 
Ja bestimmt nerve ich schon mit dem Kram ;)
Folgendes verhalten.

Delphi-Quellcode:
var
  TempFont: GpFont;
//..
begin
    if Assigned(TempFont) then
    begin
      GdipCheck(GdipDeleteFont(TempFont)); // Lösche das Font Object
      TempFont := nil;
    end;

end;
Mit D2010 und 32Bit Anwendung habe ich hier kein Problem.
Bei 64Bit kracht es weil beim Ausführen der Funktion TempFont anscheinend nicht NIL ist.
Sie wird nicht mit NIL initialisiert sondern irgendeinen imaginären wert.
Das gleiche Problem habe ich auch schon bei anderen Funktionen bemerkt.

Warum ist das so?

Es funktioniert unter 64Bit nur dann wenn ich sie selbst initialisiere.
Delphi-Quellcode:
var
  TempFont: GpFont;
//..
begin
    TempFont := nil;

    if Assigned(TempFont) then
    begin
      GdipCheck(GdipDeleteFont(TempFont)); // Lösche das Font Object
      TempFont := nil;
    end;

end;
In D2010 bekomme ich dann aber eine Warnung.. Variable wird nicht verwendet.
Sehr seltsam dieses Verhalten.
Man sollte wirklich mal einen Thread erstelle Wie Migriert man richtig zu 64Bit
Die Fehler die ich bisher schon gefunden habe sind wirklich kurios bis weilen.

Seltsamerweise tritt dieser Fehler aber nur unter Win10 auf das kommt noch dazu.

gruss

arnof 1. Sep 2018 09:08

AW: Variablen nicht NIL 64Bit
 
also; ich habe erst gestern darüber diskutiert, das Variablen nicht nil sind, wenn man Sie definiert und ich sicher sein muss das Sie nil sind.

Fazit:

Global Variablen sind das; hier kann man aber auch angeben:


var
TempFont: GpFont=nil;


Das geht bei localen Variablen nicht und diese sind auch nicht nil bei der Definition.

Möglich das es einen Compiler Schalter gibt, den Du vieleicht im alten Delphi angeschaltet hast; ich weiss das aber nicht ob es den gibt.

Also ich definiere Variablen Inhalte, wenn ich einen definierten Wert brauche.

Ghostwalker 1. Sep 2018 09:10

AW: Variablen nicht NIL 64Bit
 
Das hat noch nicht mal was mit 32-Bit/64-Bit zu tun. Generel haben Variablen erstmal einen undefinierten Inhalt, bis sie initialisiert werden (egal ob das nun Zeiger, Methodenzeiger oder sonstwas sind).

Das ganze ist mir schon mit 32-Bit passiert und ich geh mal davon aus das das mit 64-Bit nicht anders ist.

:-D

EWeiss 1. Sep 2018 09:53

AW: Variablen nicht NIL 64Bit
 
Zitat:

Zitat von Ghostwalker (Beitrag 1412186)
Das hat noch nicht mal was mit 32-Bit/64-Bit zu tun. Generel haben Variablen erstmal einen undefinierten Inhalt, bis sie initialisiert werden (egal ob das nun Zeiger, Methodenzeiger oder sonstwas sind).

Das ganze ist mir schon mit 32-Bit passiert und ich geh mal davon aus das das mit 64-Bit nicht anders ist.

:-D

Das Problem ist mit 32Bit\64Bit und D2010 (Win7) stürzt die Anwendung nicht ab.
In 64Bit unter Win10 stürzt sie ab bei gleichen Code..

Nun gut warum weiter aufregen ich werde sie selbst entsprechend definieren und gut ist..
Muss die Warnung von D2010 halt ignorieren.

Danke.

p80286 1. Sep 2018 09:59

AW: Variablen nicht NIL 64Bit
 
Ich initialisiere jede Variable, egal ob lokal oder global, weil es mir zu blöde ist mir zu merken wann durch "Zauberhand" eine Initialisierung vorgenommen wird und wann nicht.

Gruß
K-H

EWeiss 1. Sep 2018 10:04

AW: Variablen nicht NIL 64Bit
 
Zitat:

Zitat von p80286 (Beitrag 1412192)
Ich initialisiere jede Variable, egal ob lokal oder global, weil es mir zu blöde ist mir zu merken wann durch "Zauberhand" eine Initialisierung vorgenommen wird und wann nicht.

Gruß
K-H

Jo man lernt aus Erfahrung ;)
Aber doch seltsam das es ohne zu murren unter Win7 geht und Win10 stürzt das teil klanglos ab. ;)

gruss

mensch72 1. Sep 2018 10:49

AW: Variablen nicht NIL 64Bit
 
Versuch der Erklärung in 4 Teilen, das es besser it nicht vom Compiler alle Variablen mit Null/Nil zu initialisieren:
1. es ist gut für Timing, den es kann bei GigaByte größen schlicht etwas dauern
2. es ist gut für die Virtualisierbarkeit, denn der VM Speichermanager rennt eben nicht gleich "bockierend" über den gesamten LokalVar Speicher, wenn in der Funktion von 6Variablen ev. nur drei real if bedingt benutzt werden
3. der Programmierer denkt nach, wenn er gezielt auch mit 0/NULL/NIL vorbelegt... eine stets bewußte Definition hilft insbesonders anderen beim Code Lesen ungemein, denn dann ist stets sofort ersichlich "der Startwert ist irgendwie wichtig" bzw. "der Startwert ist völlig egal"(heißt man muss beim Lesen im Weitern nur auf die Zuweisung achten)
4. Win7 als Vista Nachfolger wurde von MS bewußt sicher gestaltet, Win10/64 ist intern wieder höher optimiert und der WinSpeicherManager "nullt" angeforderten Speicher wirklich nur noch, wenn bei GlobalAlloc auch das ZEROMEMORY Flag mit angegeben wird... frühere WinVersionen haben stets um alle Speicherreservierungen noch ein paar Byte "Sicherheitspuffer" reserviert, sodass die ersten paar lokal Variablen eben doch stets "genullt" waren... nur war das eben ein GoodWill von MS für frühere Windowsversionen

EWeiss 1. Sep 2018 11:11

AW: Variablen nicht NIL 64Bit
 
Nun das sind wieder Beispiele bei den man als Laie voll auf die Nase fallen kann da man sich nicht sicher sein kann wie es nun korrekt sein muss.
Jeder hat eine andere Meinung und festgelegt scheint da wieder mal nichts zu sein.
Ich starte meinen Player im Vollbild Win7 alles wunderbar.. gehe nach Win10 und Crash wegen einer einzelnen Variable die man vorher nicht auf NIL gesetzt hat.

Das gleiche mit meinem OpenFileDialog.
Nun gut ist halt so.

Manchmal habe ich den Eindruck die haben da mehr verschlimmbessert.

gruss

Medium 1. Sep 2018 12:10

AW: Variablen nicht NIL 64Bit
 
Da hat niemand etwas verschlimmbessert. Wenn man lokale Variablen nicht selbst initialisiert, verlässt man sich auf sein Glück. Bei deinem 32 Bit Kompilat hattest du halt das Glück, das an der Stelle auf dem Stack zufällig die "erwartete" 0 steht. Beim 64 Bit Kompilat steht aber etwas anderes drin. Nicht initialisiert = "kann irgendwas sein, halt auch 0". Dieses Verhalten ist seit mindestens Delphi 1 so, und auch so dokumentiert. Und der Compiler warnt nicht aus Spaß an der Freud ebenfalls.
Ich selbst werte fehlende Initialisierung sogar als groben Fehler im Code. Meiner Meinung nach sollte Delphi in solchen Fällen das Kompilieren ebenso verwehren wie bei Syntaxfehlern - aber das sind Designfragen die der Kompilerbauer entscheiden darf.

EWeiss 1. Sep 2018 12:16

AW: Variablen nicht NIL 64Bit
 
Zitat:

Und der Compiler warnt nicht aus Spaß an der Freud ebenfalls.
Ja er warnt mich das diese Variable keine Verwendung findet.. also nicht benutzt wird.
Wenn es das ist was du meinst?

Du siehst also die Comunity Edition gibt keine Warnung aus D2010 hingegen schon!
Wem soll man nun glauben schenken.. Unter D2010 ist in dieser Zeile nicht mal ein Breakpoint.

Also genauer diese!
Zitat:

[DCC Hinweis] uDrawText.pas(155): H2077 Auf 'TempFont' zugewiesener Wert wird niemals benutzt
Was denn nun!
Weise ich TmpFont NIL zu spuckt der Compiler ne Warnung aus.
Tue ich es nicht dann kracht es unter Win10 64Bit.

gruss

Schokohase 1. Sep 2018 12:37

AW: Variablen nicht NIL 64Bit
 
Der Compiler hat doch absolut Recht mit der Warnung
Delphi-Quellcode:
procedure Test;
var
  SomeThing:TObject;
begin
  if Assigned(SomeThing) then
    begin
      SomeThing.Free();
      SomeThing := nil;
    end;
end;
Code:
[dcc32 Hinweis] Project1.dpr(17): H2077 Auf 'SomeThing' zugewiesener Wert wird niemals benutzt
[dcc32 Warnung] Project1.dpr(14): W1036 Variable 'SomeThing' ist möglicherweise nicht initialisiert worden
und jetzt mal so
Delphi-Quellcode:
procedure Test;
var
  SomeThing:TObject;
begin
  SomeThing := nil;
  if Assigned(SomeThing) then
    begin
      SomeThing.Free();
      SomeThing := nil;
    end;
end;
Code:
[dcc32 Hinweis] Project1.dpr(18): H2077 Auf 'SomeThing' zugewiesener Wert wird niemals benutzt
Wollen wir diese letzte Warnung auch noch wegbekommen?
Delphi-Quellcode:
procedure Test;
var
  SomeThing:TObject;
begin
  SomeThing := nil;
  if Assigned(SomeThing) then
    begin
      SomeThing.Free();
      SomeThing := nil;
    end;

  FreeAndNil( SomeThing );
end;
Bitteschön.

Jetzt die Preisfrage: Warum ist das so (und vor allem ist das unter Delphi 10.2.3 so völlig korrekt)?

Wer es weiß, darf sich ein Bonbon nehmen.

EWeiss 1. Sep 2018 12:42

AW: Variablen nicht NIL 64Bit
 
Zitat:

Jetzt die Preisfrage: Warum ist das so (und vor allem ist das unter Delphi 10.2.3 so völlig korrekt)
Die Antwort:
TempFont := Nil steht in der ersten Zeile..
Aber ihr scheint es nicht zu verstehen.

Delphi-Quellcode:
var
   TempFont: GpFont;
//..
begin
     TempFont := nil;

     if Assigned(TempFont) then
     begin
       GdipCheck(GdipDeleteFont(TempFont)); // Lösche das Font Object
       TempFont := nil;
     end;

end;
Oder kannst du sehen das irgendwo ein Try final block oder ähnliches steht was die Warnung berechtigter weise ausgibt?
Zitat:

Delphi 10.2.3 so völlig korrekt
NÖ weil sie unter Delphi2010 ausgespuckt wird und nicht unter Delphi 10.2.3..

Zitat:

Jetzt die Preisfrage:
Brauchst du eine Brille oder liest du meine Beiträge nicht!
Zitat:

Wer es weiß, darf sich ein Bonbon nehmen.
Du dir zwei wenn du meine Beiträge mal vorher lesen würdest.

Zudem TempFont wird weiter unten im Code noch verwendet habe den Teil nur nicht addiert. bzw.. zwischen TempFont := Nil und Asssign

gruss

Schokohase 1. Sep 2018 12:47

AW: Variablen nicht NIL 64Bit
 
Da du offensichtlich die Hinweise nicht korrekt deuten kannst hier eine kleine Hilfestellung.

Delphi-Quellcode:
procedure Test;
var
  SomeThing:TObject;
begin
  if Assigned(SomeThing) then
// [dcc32 Warnung] Project1.dpr(14): W1036 Variable 'SomeThing' ist möglicherweise nicht initialisiert worden
    begin
      SomeThing.Free();
      SomeThing := nil;
// [dcc32 Hinweis] Project1.dpr(17): H2077 Auf 'SomeThing' zugewiesener Wert wird niemals benutzt
    end;
end;
Ich habe den Hinweistext unter die betreffende Codezeile eingefügt.

Wird es jetzt klarer?

Das andere Beipiel, was deinem am nächsten kommt
Delphi-Quellcode:
procedure Test;
var
  SomeThing:TObject;
begin
  SomeThing := nil;
  if Assigned(SomeThing) then
    begin
      SomeThing.Free();
      SomeThing := nil;
// [dcc32 Hinweis] Project1.dpr(18): H2077 Auf 'SomeThing' zugewiesener Wert wird niemals benutzt
    end;
end;

EWeiss 1. Sep 2018 12:48

AW: Variablen nicht NIL 64Bit
 
lies mein Edit! ;)

gruss

Schokohase 1. Sep 2018 12:51

AW: Variablen nicht NIL 64Bit
 
Dann zeig doch mal ein komplettes Beispiel, wo die falschen Warnungen geworfen werden.

Bei dem was du hier zeigst kann ich aktuell nur ein korrektes Verhalten sehen/nachvollziehen.

EWeiss 1. Sep 2018 12:57

AW: Variablen nicht NIL 64Bit
 
Zitat:

Zitat von Schokohase (Beitrag 1412207)
Dann zeig doch mal ein komplettes Beispiel, wo die falschen Warnungen geworfen werden.

Bei dem was du hier zeigst kann ich aktuell nur ein korrektes Verhalten sehen/nachvollziehen.

Nicht schon wieder mit deinen Beispielen das hatten wir schon, aber gut..

Delphi-Quellcode:
var
  Graphics: LONG_PTR;
  Fam: GpFontFamily;
  TempFont: GpFont;
  rb: TRect;
  xWidth, YHeight: Integer;
  strFormat: GPSTRINGFORMAT;
  boundingBox, layoutRect: TGPRectF;

begin

  result := GenericError;
  strFormat := nil;
  Fam := nil;
  TempFont := nil; ..// hier kommt Warnung unter D2010 in Delphi 10.2.3 nicht. Deshalb war es vorher nicht addiert.
                     // habe es aber jetzt trotzdem addiert und ignoriere die Warnung.
  Graphics := 0;

  try
    GdipCheck(GdipCreateFontFamilyFromName(PWideChar(UseFont), FontCollection, Fam));
    if Assigned(Fam) then
    begin
      GdipCheck(GdipCreateFont(Fam, UseSize, FontStyle, 2, TempFont));
      if Assigned(TempFont) then
      begin
        // 0: Kein Schatten
        // Positiver wert für Schatten Rechts
        // Negativer wert für Schatten links
        // Zeichne den string
        GdipCheck(GdipCreateStringFormat(0, 0, strFormat));
        GdipCheck(GdipCreateFromHDC(DC, Graphics));

        FillChar(boundingBox, SizeOf(boundingBox), 0);
        FillChar(layoutRect, SizeOf(layoutRect), 0);

        GdipCheck(GdipMeasureString(Graphics, PWideChar(UseText), length(UseText), TempFont,
            @layoutRect, strFormat, @boundingBox, nil, nil));

        if Assigned(strFormat) then
          GdipCheck(GdipDeleteStringFormat(strFormat));

        if not WordWrap then
        begin
          xWidth := round(boundingBox.Width + 0.5);
          YHeight := round(boundingBox.Height + 1.5);
          if BlurText then
          begin
            SetRect(rb, rec.Left, rec.Top, rec.Left + xWidth, rec.Top + YHeight);
            BlurTextPlus(DC, UseText, rb, TempFont, BlurColor, 4, UseStrFormat);
          end;
        end else
        begin
          xWidth := rec.Right;
          YHeight := rec.Bottom;
          if BlurText then
          begin
            SetRect(rb, rec.Left, rec.Top, rec.Left + xWidth, rec.Top + YHeight);
            BlurTextPlus(DC, UseText, rb, TempFont, BlurColor, 4, UseStrFormat);
          end;
        end;

        result := DrawStringFormatedEx(Graphics, UseText, rec.Left, rec.Top, xWidth, YHeight,
          ColrARGB, SkinEngine.SK_TEXTRENDERING, TempFont, ShadowOffset, UseStrFormat);
      end;
    end;
  finally
    if Graphics <> 0 then
    begin
      GdipCheck(GdipDeleteGraphics(Graphics));
      Graphics := 0;
    end;

    if Assigned(TempFont) then
    begin
      GdipCheck(GdipDeleteFont(TempFont)); // Und hier kracht es unter Win10 wenn TempFont mit irgendwas gefüllt wird. (In D2010 nicht! )
      TempFont := nil;
    end;

    if Assigned(Fam) then
    begin
      GdipCheck(GdipDeleteFontFamily(Fam));
      Fam := nil;
    end;
  end;

end;

Uwe Raabe 1. Sep 2018 13:08

AW: Variablen nicht NIL 64Bit
 
Zitat:

Zitat von EWeiss (Beitrag 1412204)
NÖ weil sie unter Delphi2010 ausgespuckt wird und nicht unter Delphi 10.2.3..

Dann compilierst du was anderes oder mehr als hier gezeigt.

Ich habe mal die nötigen GDI+ Deklarationen extrahiert, da es die unter D2010 im Standard noch nicht gibt. Dieses Programm
Delphi-Quellcode:
program Test;

type
  Status = (Ok, GenericError, InvalidParameter, OutOfMemory, ObjectBusy, InsufficientBuffer, NotImplemented, Win32Error,
    WrongState, Aborted, FileNotFound, ValueOverflow, AccessDenied, UnknownImageFormat, FontFamilyNotFound,
    FontStyleNotFound, NotTrueTypeFont, UnsupportedGdiplusVersion, GdiplusNotInitialized, PropertyNotFound,
    PropertyNotSupported);
  TStatus = Status;

  GpStatus = TStatus;

type
  GpFont = Pointer;

function GdipDeleteFont(font: GpFont): GpStatus;
begin
  Result := Ok;
end;

procedure Main;
var
  TempFont: GpFont;
begin
  TempFont := nil;

  if Assigned(TempFont) then begin
    GdipDeleteFont(TempFont);
    TempFont := nil; // H2077 Auf 'TempFont' zugewiesener Wert wird niemals benutzt
  end;
end;

begin
  Main;
end.
gibt sowohl unter D2010 als auch unter Delphi 10.2.3 nur einen Hinweis
Zitat:

H2077 Auf 'TempFont' zugewiesener Wert wird niemals benutzt
für die zweite Zuweisung von TempFont innerhalb des if-then-Blocks aus. Die erste Zuweisung auf nil wird nicht bemängelt. Die beiden Compiler arbeiten in diesem Fall also identisch und auch korrekt.

EWeiss 1. Sep 2018 13:12

AW: Variablen nicht NIL 64Bit
 
Zitat:

Die beiden Compiler arbeiten in diesem Fall also identisch und auch korrekt.
Das ist ja was mich stutzig macht und warum bei mir so seltsame dinge auftreten.. keine Ahnung was da bei mir los ist.
Eigentlich dürfte diese Warnung nicht auftreten.

Ich lasse es jetzt drin stört nicht weiter.

Danke für den Test!

Delphi-Quellcode:
  if Assigned(TempFont) then begin
     GdipDeleteFont(TempFont);
     TempFont := nil; // H2077 Auf 'TempFont' zugewiesener Wert wird niemals benutzt
   end;
Ist logisch weil du den Font vorher nicht verwendest.
Aber Ich. Siehe!
Assigned(TempFont) steht ja erst hinter dieser zeile ;)

Delphi-Quellcode:
        GdipCheck(GdipMeasureString(Graphics, PWideChar(UseText), length(UseText), TempFont,
             @layoutRect, strFormat, @boundingBox, nil, nil));
Eigentlich müsste es unter beiden Systemen krachen wenn TempFont nicht definiert wurde.
Liegt vielleicht doch an der GDIPlus. Das die 32Bit den Fehler ignoriert aber die 64Bit nicht.
Na ja es läuft ja jetzt.

gruss

Schokohase 1. Sep 2018 13:51

AW: Variablen nicht NIL 64Bit
 
Zitat:

Zitat von EWeiss (Beitrag 1412211)

Delphi-Quellcode:
  if Assigned(TempFont) then begin
     GdipDeleteFont(TempFont);
     TempFont := nil; // H2077 Auf 'TempFont' zugewiesener Wert wird niemals mehr benutzt
   end;
Ist logisch weil du den Font vorher nicht verwendest.
Aber Ich. Siehe!

Du hast den Sinn der Warnung immer noch nicht verstanden.

Du weist der Variablen einen Wert zu, aber dieser Wert wird NACH dieser Code-Zeile niemals verwendet. Diese Zeile ist also prinzipiell überflüssig.

Ob du vorher die Variable mit ihrem Inhlat verwendet hast oder nicht, spielt hier keine Geige. Es geht um diese Zuweisung und den Code danach.

Dein Code könnte also so aussehen
Delphi-Quellcode:
var
  Graphics: LONG_PTR;
  Fam: GpFontFamily;
  TempFont: GpFont;
  rb: TRect;
  xWidth, YHeight: Integer;
  strFormat: GPSTRINGFORMAT;
  boundingBox, layoutRect: TGPRectF;

begin

  result := GenericError;
  strFormat := nil;
  Fam := nil;
  TempFont := nil; ..// hier kommt Warnung unter D2010 in Delphi 10.2.3 nicht. Deshalb war es vorher nicht addiert.
                     // habe es aber jetzt trotzdem addiert und ignoriere die Warnung.
  Graphics := 0;

  try
    // ... schnipp ... schnapp ...
  finally
    if Graphics <> 0 then
    begin
      GdipCheck(GdipDeleteGraphics(Graphics));
      //Graphics := 0;
    end;

    if Assigned(TempFont) then
    begin
      GdipCheck(GdipDeleteFont(TempFont)); // Und hier kracht es unter Win10 wenn TempFont mit irgendwas gefüllt wird. (In D2010 nicht! )
      //TempFont := nil;
    end;

    if Assigned(Fam) then
    begin
      GdipCheck(GdipDeleteFontFamily(Fam));
      //Fam := nil;
    end;
  end;

end;
und müsste jetzt 3 Warnungen weniger produzieren

EWeiss 1. Sep 2018 13:57

AW: Variablen nicht NIL 64Bit
 
Zitat:

Du weist der Variablen einen Wert zu, aber dieser Wert wird NACH dieser Code-Zeile niemals verwendet. Diese Zeile ist also prinzipiell überflüssig.
siehe mein code vielleicht verstehst du es dann.

was steht hier
Delphi-Quellcode:
        GdipCheck(GdipMeasureString(Graphics, PWideChar(UseText), length(UseText), TempFont,
             @layoutRect, strFormat, @boundingBox, nil, nil));
und was kommt dann?

Delphi-Quellcode:
     if Assigned(TempFont) then
     begin
       GdipCheck(GdipDeleteFont(TempFont)); // Und hier kracht es unter Win10 wenn TempFont mit irgendwas gefüllt wird. (In D2010 nicht! )
       TempFont := nil;
     end;
Das // ... schnipp ... schnapp ... hättest du besser mal nicht entfernt.
Denn das ist die Zeile in der TmpFont verwendet wird.
Du wolltest doch ein Beispiele warum verwendest du es dann nicht so wie gezeigt und wirfst den benötigten Part einfach raus.
Sorry du bist einfach nur Lustig.

Thema ist erledigt..

gruss

Medium 3. Sep 2018 08:57

AW: Variablen nicht NIL 64Bit
 
Ich bin mir ziemlich sicher, dass das "schnipp schnapp" nur dazu diente, Teile vom Code in denen er nichts geändert hat nicht unnötig nochmals zu posten um den Abschnitt klein und übersichtlich zu halten. Ob da etwas steht oder nicht macht für den genannten Weg hin zur "Compilerhinweis-Freiheit" nämlich keinen Unterschied. Manchmal frage ich mich, warum du überhaupt Fragen stellst, wenn du am Ende eh nicht wirklich Hilfe annimmst und (meist fälschlicherweise) meinst es wäre doch eh von Anfang an alles richtig bei dir. Komisches Verhalten um ehrlich zu sein. Auch nicht lustig.

Stevie 3. Sep 2018 12:20

AW: Variablen nicht NIL 64Bit
 
Ich hab mal an die entsprechenden Stellen Kommentare gepackt und sie mit SG markiert.

Delphi-Quellcode:
var
  Graphics: LONG_PTR;
  Fam: GpFontFamily;
  TempFont: GpFont;
  rb: TRect;
  xWidth, YHeight: Integer;
  strFormat: GPSTRINGFORMAT;
  boundingBox, layoutRect: TGPRectF;

begin

  result := GenericError;
  strFormat := nil;
  Fam := nil;
  TempFont := nil; ..// hier kommt Warnung unter D2010 in Delphi 10.2.3 nicht. Deshalb war es vorher nicht addiert.
                     // habe es aber jetzt trotzdem addiert und ignoriere die Warnung.

                     // SG: Einige Hinweise in Bezug auf nicht initialisierte Variablen oder nicht benutzte Werte
                     // wurden erst jüngst in 10.1 oder 10.2 gefixt, siehe Changelogs/fixed issues, daher fälschlicherweise Hinweis unter Delphi 2010
  Graphics := 0;

  try
    GdipCheck(GdipCreateFontFamilyFromName(PWideChar(UseFont), FontCollection, Fam));
    if Assigned(Fam) then
    begin
      GdipCheck(GdipCreateFont(Fam, UseSize, FontStyle, 2, TempFont));
      if Assigned(TempFont) then
      begin
        // 0: Kein Schatten
        // Positiver wert für Schatten Rechts
        // Negativer wert für Schatten links
        // Zeichne den string
        GdipCheck(GdipCreateStringFormat(0, 0, strFormat));
        GdipCheck(GdipCreateFromHDC(DC, Graphics));

        FillChar(boundingBox, SizeOf(boundingBox), 0);
        FillChar(layoutRect, SizeOf(layoutRect), 0);

        GdipCheck(GdipMeasureString(Graphics, PWideChar(UseText), length(UseText), TempFont,
            @layoutRect, strFormat, @boundingBox, nil, nil));

        if Assigned(strFormat) then
          GdipCheck(GdipDeleteStringFormat(strFormat));

        if not WordWrap then
        begin
          xWidth := round(boundingBox.Width + 0.5);
          YHeight := round(boundingBox.Height + 1.5);
          if BlurText then
          begin
            SetRect(rb, rec.Left, rec.Top, rec.Left + xWidth, rec.Top + YHeight);
            BlurTextPlus(DC, UseText, rb, TempFont, BlurColor, 4, UseStrFormat);
          end;
        end else
        begin
          xWidth := rec.Right;
          YHeight := rec.Bottom;
          if BlurText then
          begin
            SetRect(rb, rec.Left, rec.Top, rec.Left + xWidth, rec.Top + YHeight);
            BlurTextPlus(DC, UseText, rb, TempFont, BlurColor, 4, UseStrFormat);
          end;
        end;

        result := DrawStringFormatedEx(Graphics, UseText, rec.Left, rec.Top, xWidth, YHeight,
          ColrARGB, SkinEngine.SK_TEXTRENDERING, TempFont, ShadowOffset, UseStrFormat);
      end;
    end;
  finally
    if Graphics <> 0 then
    begin
      GdipCheck(GdipDeleteGraphics(Graphics));
      Graphics := 0;
    end;

    if Assigned(TempFont) then // SG: Dieser Code kann ausgeführt werden wenn z.B. oben if Assigned(Fam) false lieferte.
                               // Dann wird TempFont nämlich nicht durch GdipCreateFont gesetzt und ist somit nicht initialisiert
                               // Da nun aber auf dem Stack unter 32bit "immer" nil stand, hat man hier Glück gehabt
    begin
      GdipCheck(GdipDeleteFont(TempFont)); // Und hier kracht es unter Win10 wenn TempFont mit irgendwas gefüllt wird. (In D2010 nicht! )
      TempFont := nil;
    end;

    if Assigned(Fam) then
    begin
      GdipCheck(GdipDeleteFontFamily(Fam));
      Fam := nil;
    end;
  end;

end;

EWeiss 3. Sep 2018 12:57

AW: Variablen nicht NIL 64Bit
 
Zitat:

// SG: Einige Hinweise in Bezug auf nicht initialisierte Variablen oder nicht benutzte Werte
// wurden erst jüngst in 10.1 oder 10.2 gefixt, siehe Changelogs/fixed issues, daher fälschlicherweise Hinweis unter Delphi 2010
Und genau das war mein Problem weshalb ich TempFont := nil; vorher nicht selbst definiert und auf NIL gesetzt habe.
Das haben aber einige Leute hier nicht verstanden und haben versucht mir was zu erklären was mir selbst vorher schon klar war.
Deshalb habe ich auf diese Beiträge auch nicht mehr bzw. patzig geantwortet.

Durch das setzen von NIL ist ja nun alles geklärt und das Thema erledigt.
Auch wenn D2010 mir immer noch falsche Hinweise ausgibt.. sei's drum.
Man baut sich solche unnötigen Fehler selbst ein weil man sich auf den Compiler und seinen Warnungen verlässt
stimmen diese nicht nun dann kracht es wie hier geschehen.

@Stevie Danke du hast mich verstanden und nicht versucht mich zu belehren.

PS:
Zitat:

Manchmal frage ich mich, warum du überhaupt Fragen stellst, wenn du am Ende eh nicht wirklich Hilfe annimmst und (meist fälschlicherweise) meinst es wäre doch eh von Anfang an alles richtig bei dir. Komisches Verhalten um ehrlich zu sein. Auch nicht lustig.
Vielleicht liegt es ganz einfach daran das ihr meine Beiträge nur überfliegt und nicht lest was dort steht.
Ich habe von Anfang an deutlich darauf hingewiesen!
Zitat:

In D2010 bekomme ich dann aber eine Warnung.. Variable wird nicht verwendet.
Die ganzen Seitenlangen Belehrungen wie oder warum eine Variable nicht initialisiert wird hättet ihr euch sparen können das ist und war mir vorher schon bekannt.
Es hatte unter 32Bit keinerlei Auswirkung nachdem ich diese auf Grund der Warnung entfernt hatte, hingegen unter 64Bit schon.

gruss

stahli 3. Sep 2018 14:18

AW: Variablen nicht NIL 64Bit
 
[OT]
@Emil,

Du musst die Beiträge einfach nicht als Angriff gegen Dich auffassen.
Wir versuchen, uns hier gegenseitig zu helfen.
Kann sein, dass man sich nicht immer komplett versteht, dann kann man versuchen, das auszuräumen.
Dennoch ist eine gut gemeinte Antwort eine nette Sache, auch wenn sie nicht zum Erfolg führt oder gar die Frage gar nicht beantwortet.

Ich hatte mir Deine Beiträge auch gerade durchgelesen, um evtl. helfen zu können. Deine Antworten machten es nicht einfacher, das Problem nachzuvollziehen.

Offensichtlich hat es Stevie ja jetzt aufklären können.

ME sollte aber das letzte "TempFont := nil;" einen Hinweis erzeugen, dass die Variable nicht mehr genutzt wird. Vielleicht ist das aber auch in verschiedenen Delphiversionen unterschiedlich...

@all:
Lässt sich dieser Hinweis eigentlich abschalten? Ich würde manchmal eine solche abschließende Zuweisung der Übersichtlichkeit halber gern vornehmen. Um keine Compiler-Hinweise zu erhalten schmeiße ich die dann aber doch raus.

[/OT]

EWeiss 3. Sep 2018 14:25

AW: Variablen nicht NIL 64Bit
 
Zitat:

Du musst die Beiträge einfach nicht als Angriff gegen Dich auffassen.
Wir versuchen, uns hier gegenseitig zu helfen.
Kann sein, dass man sich nicht immer komplett versteht, dann kann man versuchen, das auszuräumen.
Dennoch ist eine gut gemeinte Antwort eine nette Sache, auch wenn sie nicht zum Erfolg führt oder gar die Frage gar nicht beantwortet.
Du hast recht.. Danke.
Zitat:

ME sollte aber das letzte "TempFont := nil;" einen Hinweis erzeugen, dass die Variable nicht mehr genutzt wird.
Keine Ahnung was da schief läuft werde mal neu Installieren.

gruss

Stevie 3. Sep 2018 14:38

AW: Variablen nicht NIL 64Bit
 
Zitat:

Zitat von stahli (Beitrag 1412337)
Lässt sich dieser Hinweis eigentlich abschalten? Ich würde manchmal eine solche abschließende Zuweisung der Übersichtlichkeit halber gern vornehmen. Um keine Compiler-Hinweise zu erhalten schmeiße ich die dann aber doch raus.

Einzelne Hints lassen sich nicht abschalten (im Gegensatz zu Warnings) - man kann sie nur komplett aus oder an schalten.

Zitat:

Zitat von stahli (Beitrag 1412337)
ME sollte aber das letzte "TempFont := nil;" einen Hinweis erzeugen, dass die Variable nicht mehr genutzt wird. Vielleicht ist das aber auch in verschiedenen Delphiversionen unterschiedlich...

Wie schon gesagt, ist die Flow Analyse in einigen älteren Versionen noch etwas fehlerhaft, so dass manchmal Hints auftauchen, wo sie es nicht sollten und umgekehrt. Gerade, was Benutzung in try/finally oder excepts oder if statements angeht.

Uwe Raabe 3. Sep 2018 14:51

AW: Variablen nicht NIL 64Bit
 
Zitat:

Zitat von stahli (Beitrag 1412337)
Lässt sich dieser Hinweis eigentlich abschalten? Ich würde manchmal eine solche abschließende Zuweisung der Übersichtlichkeit halber gern vornehmen. Um keine Compiler-Hinweise zu erhalten schmeiße ich die dann aber doch raus.

Wie Stevie schon sagte, kann man einzelne Hinweise global nicht abschalten. Allerdings kannst du die betreffende Zuweisung ausklammern (Hinweise (Delphi)):
Delphi-Quellcode:
{$HINTS OFF}
TempFont := nil;
{$HINTS ON}
Ob das nun allerdings der Lesbarkeit förderlich ist sei mal dahingestellt.

EWeiss 3. Sep 2018 14:58

AW: Variablen nicht NIL 64Bit
 
Es ist ja eine Warnung kein Hint (Hinweis)

gruss

Uwe Raabe 3. Sep 2018 15:07

AW: Variablen nicht NIL 64Bit
 
Zitat:

Zitat von EWeiss (Beitrag 1412341)
Es ist ja eine Warnung kein Hint (Hinweis)

Delphi-Quellcode:
TempFont := nil; // H2077 Auf 'TempFont' zugewiesener Wert wird niemals benutzt


H2077 ist ein Hinweis. Warnungen haben W-Nummern. Siehe auch hier:
Zitat:

[dcc32 Hinweis] Project1.dpr(17): H2077 Auf 'SomeThing' zugewiesener Wert wird niemals benutzt
[dcc32 Warnung] Project1.dpr(14): W1036 Variable 'SomeThing' ist möglicherweise nicht initialisiert worden

EWeiss 3. Sep 2018 15:24

AW: Variablen nicht NIL 64Bit
 
OK sorry ;)

gruss

Blup 12. Sep 2018 15:33

AW: Variablen nicht NIL 64Bit
 
Manche Warnungen kann man auch einfach austricksen:
Delphi-Quellcode:
procedure InitNil(out AObject);
begin
  TObject(AObject) := nil;
end;

InitNil(TempFont);
Hab jetzt aber nicht mit 64 Bit getestet.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:00 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