Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   FreePascal (https://www.delphipraxis.net/74-freepascal/)
-   -   Typisierte vs. Untypisierte Konstante (https://www.delphipraxis.net/135671-typisierte-vs-untypisierte-konstante.html)

FAlter 15. Jun 2009 20:39


Typisierte vs. Untypisierte Konstante
 
Hi,

Delphi-Quellcode:
program Project1;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes;

const
  const1 = 'HALLO'#0#0#0;
  const2: array[0..7] of AnsiChar = 'HALLO'#0#0#0;
var
  foo: array[0..7] of AnsiChar;
begin
  foo := const1;
  WriteLn(foo = const1);
  WriteLn(foo = const2);
end.
Code:
falter@PC0303:/tmp$ ./project1 
FALSE
TRUE
falter@PC0303:/tmp$
Warum liefert das erste false?

Gruß
Felix

Apollonius 15. Jun 2009 20:48

Re: Typisierte vs. Untypisierte Konstante
 
Der erste Vergleich konvertiert vermutlich beide Operanden nach PChar, sodass ein reiner Zeigervergleich fehlschlägt. Beim zweiten Vergleich hingegen werden zwei statische Arrays verglichen, was durch Vergleich des Speicherinhalts erfolgt. Zeig doch mal den Assemblercode.

Cyf 15. Jun 2009 20:55

Re: Typisierte vs. Untypisierte Konstante
 
Ansonsten, falls das nicht stimmt, hätte ich noch die Theorie, dass der Speicherinhalt verglichen wird und bei der untypisierten Variante noch eine Längenangabe des Strings davor steht. Aber ohne die Opcodes ist das nur Raten.

[Edit]

Code:
Project1.dpr.14: foo := const1;
004040D7 8B057C414000     mov eax,[$0040417c]
004040DD 8905F0874000     mov [$004087f0],eax
004040E3 8B0580414000     mov eax,[$00404180]
004040E9 8905F4874000     mov [$004087f4],eax
Project1.dpr.15: WriteLn(foo = const1);
004040EF 8D45EC          lea eax,[ebp-$14]
004040F2 BAF0874000       mov edx,$004087f0
004040F7 B908000000       mov ecx,$00000008
004040FC E8CBFAFFFF      call @LStrFromArray
00404101 8B45EC          mov eax,[ebp-$14]
00404104 BA8C414000       mov edx,$0040418c
00404109 E8D6FAFFFF      call @LStrCmp
0040410E 0F94C2           setz dl
00404111 A19C594000       mov eax,[$0040599c]
00404116 E86DF0FFFF      call @Write0Bool
0040411B E894F0FFFF      call @WriteLn
00404120 E897E9FFFF      call @_IOTest
Project1.dpr.16: WriteLn(foo = const2);
00404125 B8F0874000       mov eax,$004087f0
0040412A BA94594000       mov edx,$00405994
0040412F B908000000       mov ecx,$00000008
00404134 E81BEEFFFF      call @AStrCmp
00404139 0F94C2           setz dl
0040413C A19C594000       mov eax,[$0040599c]
00404141 E842F0FFFF      call @Write0Bool
00404146 E869F0FFFF      call @WriteLn
0040414B E86CE9FFFF      call @_IOTest

FAlter 15. Jun 2009 21:23

Re: Typisierte vs. Untypisierte Konstante
 
Hi,

Code:
(gdb) disassemble
Dump of assembler code for function main:
0x08048080 <main+0>:   push  %ebp
0x08048081 <main+1>:   mov   %esp,%ebp
0x08048083 <main+3>:   sub   $0x210,%esp
0x08048089 <main+9>:   mov   %ebx,-0x210(%ebp)
0x0804808f <main+15>:   mov   %esi,-0x20c(%ebp)
0x08048095 <main+21>:   mov   %edi,-0x208(%ebp)
0x0804809b <main+27>:   call  0x8058540 <fpc_initializeunits>
0x080480a0 <main+32>:   mov   0x8095278,%eax
0x080480a5 <main+37>:   mov   %eax,0x80b33b0
0x080480aa <main+42>:   mov   0x809527c,%eax
0x080480af <main+47>:   mov   %eax,0x80b33b4
0x080480b4 <main+52>:   call  0x805c430 <fpc_get_output>
0x080480b9 <main+57>:   mov   %eax,%edi
0x080480bb <main+59>:   mov   $0x8095284,%ebx
0x080480c0 <main+64>:   lea   -0x100(%ebp),%eax
0x080480c6 <main+70>:   push  $0x7
0x080480c8 <main+72>:   push  $0x1
0x080480ca <main+74>:   mov   $0x80b33b0,%ecx
0x080480cf <main+79>:   mov   %eax,%esi
0x080480d1 <main+81>:   mov   $0xff,%edx
0x080480d6 <main+86>:   call  0x804a6f0 <fpc_chararray_to_shortstr>
0x080480db <main+91>:   lea   -0x100(%ebp),%eax
---Type <return> to continue, or q <return> to quit---
0x080480e1 <main+97>:   mov   %ebx,%edx
0x080480e3 <main+99>:   call  0x804a6b0 <fpc_shortstr_compare_equal>
0x080480e8 <main+104>:   test  %eax,%eax
0x080480ea <main+106>:   sete  %cl
0x080480ed <main+109>:   mov   %edi,%ebx
0x080480ef <main+111>:   mov   %ebx,%eax
0x080480f1 <main+113>:   mov   $0x0,%esi
0x080480f6 <main+118>:   mov   %eax,%edx
0x080480f8 <main+120>:   mov   %esi,%eax
0x080480fa <main+122>:   call  0x805ce40 <fpc_write_text_boolean>
0x080480ff <main+127>:   call  0x8058410 <fpc_iocheck>
0x08048104 <main+132>:   mov   %ebx,%eax
0x08048106 <main+134>:   call  0x805c5a0 <fpc_writeln_end>
0x0804810b <main+139>:   call  0x8058410 <fpc_iocheck>
0x08048110 <main+144>:   call  0x805c430 <fpc_get_output>
0x08048115 <main+149>:   mov   %eax,%edi
0x08048117 <main+151>:   lea   -0x100(%ebp),%ebx
0x0804811d <main+157>:   push  $0x7
0x0804811f <main+159>:   push  $0x1
0x08048121 <main+161>:   mov   $0x809528e,%ecx
0x08048126 <main+166>:   mov   %ebx,%eax
0x08048128 <main+168>:   mov   $0xff,%edx
0x0804812d <main+173>:   call  0x804a6f0 <fpc_chararray_to_shortstr>
---Type <return> to continue, or q <return> to quit---
0x08048132 <main+178>:   lea   -0x100(%ebp),%ebx
0x08048138 <main+184>:   lea   -0x200(%ebp),%eax
0x0804813e <main+190>:   push  $0x7
0x08048140 <main+192>:   push  $0x1
0x08048142 <main+194>:   mov   $0x80b33b0,%ecx
0x08048147 <main+199>:   mov   %eax,%esi
0x08048149 <main+201>:   mov   $0xff,%edx
0x0804814e <main+206>:   call  0x804a6f0 <fpc_chararray_to_shortstr>
0x08048153 <main+211>:   lea   -0x200(%ebp),%eax
0x08048159 <main+217>:   mov   %ebx,%edx
0x0804815b <main+219>:   call  0x804a6b0 <fpc_shortstr_compare_equal>
0x08048160 <main+224>:   test  %eax,%eax
0x08048162 <main+226>:   sete  %cl
0x08048165 <main+229>:   mov   %edi,%ebx
0x08048167 <main+231>:   mov   %ebx,%eax
0x08048169 <main+233>:   mov   $0x0,%esi
0x0804816e <main+238>:   mov   %eax,%edx
0x08048170 <main+240>:   mov   %esi,%eax
0x08048172 <main+242>:   call  0x805ce40 <fpc_write_text_boolean>
0x08048177 <main+247>:   call  0x8058410 <fpc_iocheck>
0x0804817c <main+252>:   mov   %ebx,%eax
0x0804817e <main+254>:   call  0x805c5a0 <fpc_writeln_end>
0x08048183 <main+259>:   call  0x8058410 <fpc_iocheck>
---Type <return> to continue, or q <return> to quit---
0x08048188 <main+264>:   call  0x8058780 <SYSTEM_DO_EXIT>
0x0804818d <main+269>:   mov   -0x210(%ebp),%ebx
0x08048193 <main+275>:   mov   -0x20c(%ebp),%esi
0x08048199 <main+281>:   mov   -0x208(%ebp),%edi
0x0804819f <main+287>:   leave
0x080481a0 <main+288>:   ret  
End of assembler dump.
Hm... Beim ersten mal wird die Variable nach ShortString konvertiert und die nicht typisierte Konstante wohl als ShortString Konstante behandelt, beim zweiten Mal wird beides nach ShortString konvertiert und dann verglichen. Dann muss die Konstante anders aussehen als das umgewandelte Array? Na Schluss für heute,übermorgen werd ich eventuell mal gucken was bei ner Zuweisung an ShortString herauskommt und da sehen wo das Problem liegt.

@roter Kasten: Das ist von Delphi??? Liefert Delphi denn auch zwei verschiedene Ergebnisse wenn man den Code ausführt?

Gruß
Felix

Cyf 15. Jun 2009 21:36

Re: Typisierte vs. Untypisierte Konstante
 
Ja, obiger Auszug war aus dem Delphi-Debugger, dort ist auch zu sehen, dass 2 verschiedene Vergleichsfunktionen verwendet werden. Das Resultat ist wie von dir beschrieben. Wenn ich das grade richtig interpretiere, werden vorher beim Zuweisen 2 mal je 32 Bit kopiert, also eine identische Kopie als lokale Variable auf dem Stack erstellt.
Die Funktionen erwarten danach verschiedene Parameter bzw. die Parameter auch in anderer Reihenfolge und vor dem ersten Vergleich wird erst noch mal irgendwas aus dem lokalen Array umgewandelt. Ich schau morgen vielleicht noch mal genauer drüber, will jetzt grade Vektorräume und Matrizen für ein Referat morgen nicht auch noch mit Opcodes durcheinander werfen. :stupid:

jaenicke 15. Jun 2009 21:44

Re: Typisierte vs. Untypisierte Konstante
 
Zitat:

Zitat von FAlter
@roter Kasten: Das ist von Delphi???

Das ist die integrierte Assembleransicht von Delphi, ja. Dort kannst du ja auch normal Haltepunkte setzen etc.

Zitat:

Zitat von FAlter
Liefert Delphi denn auch zwei verschiedene Ergebnisse wenn man den Code ausführt?

Ich werde gleich kurz schauen.

// EDIT: Der rote Kasten macht Urlaub. :mrgreen:

himitsu 15. Jun 2009 22:41

Re: Typisierte vs. Untypisierte Konstante
 
das Array of Char wird als PChar mit maximaler Länge angesehn

und
Delphi-Quellcode:
  const1 = 'HALLO'#0#0#0;
wird als String übersetzt und beim String gehören die #0#0#0 mit zu den gültigen Daten

[add]
Delphi-Quellcode:
var
  s: String;
begin
  foo := const1;
  s := 'HALLO'#0#0#0;
  WriteLn(foo = s);
  s := PChar('HALLO'#0#0#0);
  WriteLn(foo = s);

  foo := const2;
  s := 'HALLO'#0#0#0;
  WriteLn(foo = s);
  s := PChar('HALLO'#0#0#0);
  WriteLn(foo = s);

himitsu 15. Jun 2009 22:44

Re: Typisierte vs. Untypisierte Konstante
 
[delete]

jaenicke 15. Jun 2009 23:53

Re: Typisierte vs. Untypisierte Konstante
 
Liste der Anhänge anzeigen (Anzahl: 2)
Also: Was passiert ist folgendes:
Zuerst wird LStrFromArray aufgerufen. Was macht das? Es wandelt foo in einen String um. Dessen Länge ist aber 5, da danach nur noch Nullen kommen.
So, jetzt wird LStrCmp aufgerufen. Das geht 5 Zeichen durch und merkt, dass die alle identisch sind. Da aber die Länge unterschiedlich war, war der Vergleich dennoch nicht erfolgreich.

Die unterschiedlichen Längen und der Zustand nach dem erfolgreichen Vergleich der 5 Zeichen sieht man auf den beiden Screenshots.

FAlter 16. Jun 2009 06:51

Re: Typisierte vs. Untypisierte Konstante
 
Hi,

Jetzt weiß ich, wie es bei Delphi wäre. :-) Gut zu wissen, dass es auch bei Delphi nicht identisch ist.
Wird das also bei FPC dann in einen ShortString umgewandelt, welcher die Länge 5 statt 8 hat? Denn dem Namen der aufgerufenen Funktion nach wird es in einen ShortString umgeqwandelt.

Das wäre allerdings kritisch, da dann beim zweiten Mal, wo ja zwei Umwandlungen in ShortString stattfinden, wo ich die Arrays direkt vergleiche, Die nullen hinten beide Male entfernt werden und dann werden sie nicht mit verglichen. Das heißt ja, wenn am Ende nach der ersten Null etwas anderes kommt dann fällt dies beim Vergleich nicht auf... Muss ich unbedingt morgen ausprobieren wenn ich wieder Zeit dazu habe.

Gruß
Felix


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:57 Uhr.
Seite 1 von 2  1 2      

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