Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Compilerschalter $O+ zur Code-Optimierung (https://www.delphipraxis.net/89407-compilerschalter-%24o-zur-code-optimierung.html)

daddy 30. Mär 2007 16:56


Compilerschalter $O+ zur Code-Optimierung
 
Liste der Anhänge anzeigen (Anzahl: 1)
In Delphi ist standardmäßig der Compilerschalter $O+ zur Code-Optimierung gesetzt. Dieser schießt aber scheinbar gelegentlich übers Ziel hinaus. Anbei ein kleines Programm, mit dem ein Fall aufgezeigt wird, bei dem $O+ entgegen der Aussage in der Delphi-Hilfe zu einem Fehlverhalten führt.

Die Delphi-Hilfe schreibt zur Code-Optimierung Folgendes:

Zitat:

Außer in bestimmten Testsituationen sollte die Code-Optimierung immer aktiviert sein. Die Optimierungen des Delphi-Compilers führen zu keinerlei Änderungen der Funktionsweise des Programms. Der Compiler führt keine "unsicheren" Optimierungen durch, die die Aufmerksamkeit des Programmierers auf die Probe stellen.
Tests und Kommentare jederzeit willkommen.


// EDIT:
Eine aktuellere Version des Codes findet Ihr weiter unten in Beitrag #7

Gruß, Daddy

Christian Seehase 30. Mär 2007 18:39

Re: Compilerschalter $O+ zur Code-Optimierung
 
Moin Daddy,

interessantes Verhalten :gruebel:

Ich habe noch eine 4. Alternative: Nimm keine Konstanten, sondern typisierte Konstanten, dann funktioniert es auch mit Optimierung.

jbg 30. Mär 2007 19:42

Re: Compilerschalter $O+ zur Code-Optimierung
 
Gibt dir der Compiler da nicht eine Warnung "Schleifenvariable kann außerhalb der Schleife undefiniert sein" für dein "Edit2.Text := 'Fehler ' + IntToStr(I);" ? (Habe jetzt gerade kein Delphi zur Hand)

CK_CK 30. Mär 2007 19:48

Re: Compilerschalter $O+ zur Code-Optimierung
 
Bei mir (D2006) passiert der gleiche Fehler... :gruebel:

Folgende Warnungen spuckt der Compiler aus:
Code:
[Pascal Warnung] Unit1.pas(77): W1037 FOR-Schleifenvariable 'I' kann nach Durchlauf undefiniert sein
[Pascal Warnung] Unit1.pas(84): W1036 Variable 'I' ist möglicherweise nicht initialisiert worden
[Pascal Hinweis] Unit1.pas(59): H2164 Variable 'J' wurde deklariert, aber in 'TForm1.Button1Click' nicht verwendet
Chris

jbg 30. Mär 2007 19:59

Re: Compilerschalter $O+ zur Code-Optimierung
 
Also wer Warnungen des Compiler absichtlicht misachtet, dem gehört es nicht anders. Der Bug sollte aber trotzdem im Quality Central eingetragen werden.

thkerkmann 30. Mär 2007 20:08

Re: Compilerschalter $O+ zur Code-Optimierung
 
Hi,

ich hab das grad mal mit Turbo Delphi Professional getestet.
Absolut das gleiche Verhalten. Das ist wirklich eigenartig.

Sollte man das nicht mal an CodeGear/Borland melden ?

Gruss

Thomas


Edit: hm... roter Kasten ... trotzdem absenden

Edit2:
@jbg: hast Du's selber probiert oder den Code angesehen ? Diese Warnungen lassen in keinster Weise auf dieses Verhalten schliessen, nicht mal auf irgendein anderes ungewöhnliches Verhalten. Es geht ja um das was in der Schleife passiert und nicht danach.

daddy 30. Mär 2007 21:44

Re: Compilerschalter $O+ zur Code-Optimierung
 
Liste der Anhänge anzeigen (Anzahl: 1)
@jbg
Zitat:

Also wer Warnungen des Compiler absichtlicht misachtet, dem gehört es nicht anders.
Ich habe noch einmal Änderungen vorgenommen, damit sämtliche Warnungen, von denen Ihr berichtet habt, verschwinden. Sie sind für das eigentliche Problem nicht von Bedeutung. Der Fehler tritt nach wie vor auf.

Gruß

Daddy

CK_CK 30. Mär 2007 21:46

Re: Compilerschalter $O+ zur Code-Optimierung
 
Du hast Recht! Bei mir kommen jetzt keine Warnungen mehr und trotzdem kommt der Fehler... :cyclops:

Chris

Edit: Dann wird's ja Zeit, dass du das der Quality Central meldest :stupid:

himitsu 31. Mär 2007 16:06

Re: Compilerschalter $O+ zur Code-Optimierung
 
Tja, die Codeoptimierung :angel2:

Weiter Alternative:
Tricks die Optimierung einfach selber mit 'ner "sinnlosen" Abfrage aus, wo du I direkt verwendest. ^^
Delphi-Quellcode:
if I = 0 then ;
I wird ja nicht wirklich benötigt, daher versucht der Compiler dieses rauszulösen.

for i := 0 to 3 do wird so schnell mal in ein for i := 3 to 0 do umgewandelt


Kannst es dir ja selber mal bei folgendem einfachem Code ansehn (siehe CPU-Ansicht):
Delphi-Quellcode:
for i := 0 to 3 do
  Beep;

// unoptimiert
asm
  mov  word ptr [ebp-x], 0
  @1:
  call Beep
  inc  word ptr [ebp-x]
  cmp  word ptr [ebp-x], 4
  jne  @1
end;

// optimiert
asm
  mov  word ptr [ebp-x], 4
  @1:
  call Beep
  inc  word ptr [ebp-x] // << dieses stammt wohl noch aus der nicht optimierten Variante
  dec  word ptr [ebp-x] //    und wie man sieht wird dadurch nicht mehr runtergezählt
  jnz  @1                //    inc + dec = 0
end;
Und hiernochmal speziell mit deiner ersten Schleife:
Delphi-Quellcode:
for I := 1 to C1 do
begin
  Edit1.Text := C[I];
  Edit1.Refresh;
  Sleep(500);
end;

// nicht optimiert
I := 0;
repeat
  Edit1.Text := PString(@C + i * SizeOf(String))^;
  Edit1.Refresh;
  Sleep(500);
  Inc(I);
until I = 4;

// oder leicht/nicht optimiert
I    := 0;
PTemp := @C;
repeat
  Edit1.Text := PTemp^;
  Edit1.Refresh;
  Sleep(500);
  Inc(I);
  Inc(PTemp, SizeOf(String));
until I = 4;

// optimiert
I    := 4;
PTemp := @C;
repeat
  Edit1.Text := PTemp^;
  Edit1.Refresh;
  Sleep(500);
//Inc(I); << hier wieder die zuviele Zeile bei der Optimierung
  Inc(PTemp, SizeOf(String));
  Dec(I);
until I = 0;
Tja, da hatt Delphi wohl wirklich ein Problem, :shock: (is aber schon länger bekannt)
aber wie du sieht, kannst du dieses leicht umgehen, indem du einfach dem Compiler sagst, daß du angeblich das I benötigst.

PS: 's sollte schon ein paar uralte Beiträge von mir zu soeinem Phänomen geben.
Hab damals versucht die Schleifenvariable in ASM zu verwenden, wo mich das Rückwärtszählen überraschte.
Delphi-Quellcode:
for i := 0 to 3 do
begin
  ...
    asm
      ...
      mov  eax, &i
      ...
    end;
  ...
end;

daddy 31. Mär 2007 22:40

Re: Compilerschalter $O+ zur Code-Optimierung
 
@Himitsu

Ja, war uns in der CPU-Ansicht auch aufgefallen, dass der Wert in der Schleife immer erhöht und anschließend verringert wird.

Die von Dir vorgeschlagene Möglichkeit das zu umgehen, entspricht ja eigentlich der im Programm aufgezeigten Alternative 2.

Überraschend find ich ja, dass das Entfernen des Try ... Except bzw. des IntoToStr(I) innerhalb des Except ... End das Problem ebenfalls löst. Meine Vermutung war, dass der Compiler vielleicht überhaupt erst aufgrund des Try ... Except Probleme mit der Code-Optimierung bekommt. Oder trat das von Dir damals festgestellte Problem auch ohne Try ... Except auf?

Gruß,

Daddy


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:07 Uhr.
Seite 1 von 2  1 2      

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 by Thomas Breitkreuz