AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen FreePascal Typisierte vs. Untypisierte Konstante
Thema durchsuchen
Ansicht
Themen-Optionen

Typisierte vs. Untypisierte Konstante

Ein Thema von FAlter · begonnen am 15. Jun 2009 · letzter Beitrag vom 16. Jun 2009
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von FAlter
FAlter

Registriert seit: 21. Jul 2004
Ort: Ostfildern
1.096 Beiträge
 
FreePascal / Lazarus
 
#1

Typisierte vs. Untypisierte Konstante

  Alt 15. Jun 2009, 21:39
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
Felix Alter
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: Typisierte vs. Untypisierte Konstante

  Alt 15. Jun 2009, 21:48
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.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Cyf

Registriert seit: 30. Mai 2008
407 Beiträge
 
Lazarus
 
#3

Re: Typisierte vs. Untypisierte Konstante

  Alt 15. Jun 2009, 21:55
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
Man kann einen Barbier definieren als einen, der alle diejenigen rasiert, und nur diejenigen, die sich nicht selbst rasieren.
Rasiert sich der Barbier?
  Mit Zitat antworten Zitat
Benutzerbild von FAlter
FAlter

Registriert seit: 21. Jul 2004
Ort: Ostfildern
1.096 Beiträge
 
FreePascal / Lazarus
 
#4

Re: Typisierte vs. Untypisierte Konstante

  Alt 15. Jun 2009, 22:23
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
Felix Alter
  Mit Zitat antworten Zitat
Cyf

Registriert seit: 30. Mai 2008
407 Beiträge
 
Lazarus
 
#5

Re: Typisierte vs. Untypisierte Konstante

  Alt 15. Jun 2009, 22:36
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.
Man kann einen Barbier definieren als einen, der alle diejenigen rasiert, und nur diejenigen, die sich nicht selbst rasieren.
Rasiert sich der Barbier?
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.582 Beiträge
 
Delphi 11 Alexandria
 
#6

Re: Typisierte vs. Untypisierte Konstante

  Alt 15. Jun 2009, 22:44
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 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.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#7

Re: Typisierte vs. Untypisierte Konstante

  Alt 15. Jun 2009, 23:41
das Array of Char wird als PChar mit maximaler Länge angesehn

und
  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);
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#8

Re: Typisierte vs. Untypisierte Konstante

  Alt 15. Jun 2009, 23:44
[delete]
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.582 Beiträge
 
Delphi 11 Alexandria
 
#9

Re: Typisierte vs. Untypisierte Konstante

  Alt 16. Jun 2009, 00:53
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.
Miniaturansicht angehängter Grafiken
equalbutlengthnot_317.png   arrayconstpcharcompare_141.png  
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von FAlter
FAlter

Registriert seit: 21. Jul 2004
Ort: Ostfildern
1.096 Beiträge
 
FreePascal / Lazarus
 
#10

Re: Typisierte vs. Untypisierte Konstante

  Alt 16. Jun 2009, 07:51
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
Felix Alter
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:13 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