Autor Téma: Prekladac mproblemy s prekladem inferovaneho typu polozky generickeho open array  (Přečteno 994 krát)

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 595
  • Karma: 38
    • Verze Delphi: 10.3
Výsledky jsou fakt vtipné.

Doplnil jsem:
Kód: Delphi [Vybrat]
  1. procedure Test_qword(a:qword);
  2.  begin
  3.  if a=-1 then halt;
  4. end;
  5.  
  6. procedure Test_int64(a:int64);
  7.  begin
  8.  if a=-1 then halt;
  9. end;
  10.  

a volání:

Kód: Delphi [Vybrat]
  1.         Test_qword(PInt64(@AArray[idx])^);
  2.         Test_int64(PInt64(@AArray[idx])^);
  3.  
Volání Test_qword je občas dobře, občas špatně (*1, *2...).
Volání Test_int64 je zatím vždy dobře (*8 ).


Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2399
  • Karma: 129
    • Verze Delphi: D2007, XE3, DX10
Tak v Delphi 10.3 to je taky špatně:
Kód: Delphi [Vybrat]
  1. 004D6992 FF741004         push dword ptr [eax+edx+$04]
  2. 004D6996 FF3410           push dword ptr [eax+edx]
Diky za vyzkouseni

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2399
  • Karma: 129
    • Verze Delphi: D2007, XE3, DX10
Volání Test_qword je občas dobře, občas špatně (*1, *2...).
Volání Test_int64 je zatím vždy dobře (*8 ).
Kdyz uz to mas upravene, mohl bys pls jeste vyzkouset misto qword uint64? Ono by to tedy melo byt totez.

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 595
  • Karma: 38
    • Verze Delphi: 10.3
Kdyz uz to mas upravene, mohl bys pls jeste vyzkouset misto qword uint64? Ono by to tedy melo byt totez.

Když v deklaraci procedury použiju UInt64 a volám to
Kód: Delphi [Vybrat]
  1. Test_quint(PInt64(@AArray[idx])^)
tak to nefunguje.

Pokud ale volám takto:
Kód: Delphi [Vybrat]
  1. Test_quint(PUInt64(@AArray[idx])^)
tak funguje (aspoň těch pár kompilací, co jsem zkusil).

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2399
  • Karma: 129
    • Verze Delphi: D2007, XE3, DX10
Ja jsem tedy rozlisil int64/uint64 a to se zda, ze na tech par prekladech taky funguje:
Kód: Delphi [Vybrat]
  1.     tkInt64:
  2.       begin
  3.         if ptd.MinInt64Value > ptd.MaxInt64Value then
  4.           for idx := 0 to Length(AArray) - 1 do
  5.             PutUInt64(AStream, PUInt64(@AArray[idx])^)
  6.         else
  7.           for idx := 0 to Length(AArray) - 1 do
  8.             PutInt64(AStream, PInt64(@AArray[idx])^);
  9.       end;
  10.  

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2399
  • Karma: 129
    • Verze Delphi: D2007, XE3, DX10
ale stejne si to netroufnu takhle nechat, protoze v tom listopadu to opakovane fungovalo nekolik dni, co jsem delal na unit testech a zdalo se to OK. Radsi udelam pro kazdy typ ten "rucni" preklad a udelam vypocet adresy elementu primo nezavisty na T:
Kód: Delphi [Vybrat]
  1.         p64 := @AArray[0];
  2.         for idx := 0 to Length(AArray) - 1 do
  3.         begin
  4.           PutUInt64(AStream, p64^);
  5.           inc(p64, 1);
  6.         end;
  7.  

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 595
  • Karma: 38
    • Verze Delphi: 10.3
Uděláš na to prosím report a pošleš sem link, abychom tam přidali hlas? Tohle mi připadá jako dost zásadní chyba, tak se třeba uráčí ji opravit rychle...

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2399
  • Karma: 129
    • Verze Delphi: D2007, XE3, DX10
Uděláš na to prosím report a pošleš sem link, abychom tam přidali hlas? Tohle mi připadá jako dost zásadní chyba, tak se třeba uráčí ji opravit rychle...
Kdyz uz jsem s tim stravil tolik casu, tak asi jo, jen vidim problem v tom, ze se mi stale nevede vytvorit SSCCE na par radku, kde bych to zopakoval.

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 595
  • Karma: 38
    • Verze Delphi: 10.3
Kdyz uz jsem s tim stravil tolik casu, tak asi jo, jen vidim problem v tom, ze se mi stale nevede vytvorit SSCCE na par radku, kde bych to zopakoval.

Podívám se, jestli mi to půjde nějak vypreparovat.

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 595
  • Karma: 38
    • Verze Delphi: 10.3
Kód: Delphi [Vybrat]
  1. program SSCCE_Payload;
  2.  
  3. {$APPTYPE CONSOLE}
  4. {$R *.res}
  5.  
  6. uses
  7.   System.Classes, System.Types, System.TypInfo, System.Rtti,
  8.   System.SysUtils, System.AnsiStrings, Generics.Collections,
  9.   WinApi.Windows;
  10.  
  11. type
  12.   qword = UInt64;
  13.  
  14.   TPayloadBuilder = class
  15.   public
  16.     class var Endian: TEndian;
  17.   public
  18.     // Simple types
  19.     class procedure PutUInt64(AStream: TStream; const AValue: qword);
  20.     // Collections
  21.     class procedure PutSimpleArray<T>(AStream: TStream;
  22.       const AArray: array of T);
  23.  
  24.   end;
  25.  
  26. { TPayloadBuilder }
  27.  
  28. procedure Test_quint(a:UInt64);
  29.  begin
  30. end;
  31.  
  32. procedure Test_int64(a:int64);
  33.  begin
  34. end;
  35.  
  36. class procedure TPayloadBuilder.PutSimpleArray<T>(AStream: TStream;
  37.   const AArray: array of T);
  38. var
  39.   idx: NativeInt;
  40.   x:pointer;
  41.   d:qword;
  42.  begin
  43.  for idx := 0 to Length(AArray) - 1 do begin
  44.    PutUInt64(AStream, PInt64(@AArray[idx])^); // error:   push dword ptr [eax+edx*2+$04]; push dword ptr [eax+edx*2]
  45.    Test_quint(PInt64(@AArray[idx])^); // error:   push dword ptr [eax+edx+$04]; push dword ptr [eax+edx]
  46.    Test_quint(PUInt64(@AArray[2])^);
  47.    Test_int64(PInt64(@AArray[idx])^);
  48.    d:=PInt64(@AArray[idx])^;
  49.    x:=@AArray[idx];
  50.    PutUInt64(AStream, PInt64(x)^);
  51.  end;
  52. end;
  53.  
  54. class procedure TPayloadBuilder.PutUInt64(AStream: TStream; const AValue: qword);
  55. begin
  56. end;
  57.  
  58. var
  59.   arrayOfQWords: TArray<qword>;
  60.   stream: TMemoryStream;
  61.  
  62. begin
  63.   try
  64.     arrayOfQWords := [$100000000, $100000001, $100000002, $100000003,
  65.       $100000004, $100000005, $100000006, $100000007, $100000008, $100000009];
  66.  
  67.     stream := TMemoryStream.Create;
  68.     try
  69.       TPayloadBuilder.PutSimpleArray<qword>(stream, arrayOfQWords);
  70.     finally
  71.       stream.Free;
  72.     end;
  73.  
  74.   except
  75.     on E: Exception do
  76.       Writeln(E.ClassName, ': ', E.Message);
  77.   end;
  78.  
  79. end.

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 2189
  • Karma: 97
    • Verze Delphi: D5,D2007, DXE, DXE2 + 2 poslední (Tokyo)
    • O Delphi v češtině
Ja jsem tedy rozlisil int64/uint64 a to se zda, ze na tech par prekladech taky funguje:
Kód: Delphi [Vybrat]
  1.     tkInt64:
  2.       begin
  3.         if ptd.MinInt64Value > ptd.MaxInt64Value then
  4.           for idx := 0 to Length(AArray) - 1 do
  5.             PutUInt64(AStream, PUInt64(@AArray[idx])^)
  6.         else
  7.           for idx := 0 to Length(AArray) - 1 do
  8.             PutInt64(AStream, PInt64(@AArray[idx])^);
  9.       end;
  10.  

Co jsem zkousel tak to fungovalo pokud
qword = UInt64; a  PutUInt64(AStream, PUInt64(@AArray[idx])^);
a
qword = Int64; a  PutUInt64(AStream, PInt64(@AArray[idx])^);

jakmile jsem to zacal mixoval (jako unsigned 64bit se signed), tak to zacal byt problem, jako by dochazelo k nejake konverzi. Ale je to podivne
Embarcadero MVP - Czech republic

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2399
  • Karma: 129
    • Verze Delphi: D2007, XE3, DX10
sem to zacal mixoval (jako unsigned 64bit se signed), tak to zacal byt problem, jako by dochazelo k nejake konverzi. Ale je to podivne
Divne to je, protoze ten chybny preklad se tyka jen vypoctu adresy elementu pole tj.
Kód: Delphi [Vybrat]
  1. AArray[idx]
a ten by mel byt intaktni s ohledem na dalsi (vnejsi) typecast. A nejvic divne mi prijde, ze to preklada pokazde trochu jinak, zahrnujic i spravnou verzi :o

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 595
  • Karma: 38
    • Verze Delphi: 10.3
A nejvic divne mi prijde, ze to preklada pokazde trochu jinak, zahrnujic i spravnou verzi :o

Aneb využití random() v kompilátoru :-)

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2399
  • Karma: 129
    • Verze Delphi: D2007, XE3, DX10
Aneb využití random() v kompilátoru :-)
Diky za ten SSCCE. Zajimave je, ze i kdyz z nej vyhazuju dal, tak se chyba projevuje, zatimco ve skoro identickem SSCCE, ktery jsem psal od zacatku, se chyba nevyskytuje :(

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 3833
  • Karma: 35
    • Verze Delphi: XE7 professional
Len tak pre každý prípad.
V takýchto prípadoch pre istotu "likvidujem" prípadné neviditeľné nežiadané znaky skopírovaním obsahu celej jednotky do texťáku (PsPad). Tam to, po prípadnom skontrolovaní, opäť skopírujem a vložím späť do jednotky. Ale je pravda, že som to už véééľmi dlho nepotreboval.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

 

S rychlou odpovědí můžete používat BB kódy a emotikony jako v běžném okně pro odpověď, ale daleko rychleji.

Jméno: E-mail:
Ověření:
Křestní jméno zpěváka Gotta: