The Delphi Bug List

Entry No.
502
Compiler - Code generation
Delphi generated code have an error in its address (pointer) arithmetic which can cause Access Violations. The error was found when using an array of Strings.
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 4.03 5.0 5.01 6.0 6.01 6.02 Kylix 1.0
N/AExistsExistsExistsExistsExistsExistsExistsExistsExistsExistsFixedFixedFixedFixed
Description
Reported by Primoz Gabrijelcic, on Inprise's objectpascal newsgroup; checked by Stefan Hoffmeister; Tor-Arne Riksheim
Problem: EAccessViolation exception in perfectly bug-free program.
Applies to: All versions of Delphi 3, Delphi 4 and Delphi 5.
Workaround: none known
How to reproduce:
Compile and run following program with Delphi.
--------------- cut here ---------------
{$A+,B-,C-,D+,E-,F-,G+,H+,I+,J+,K-,L+,M-,N+,O-,P+,Q-,R+,S-,T-,U-,V+,W+,X+,Y-,Z1}
{$APPTYPE CONSOLE}

program Test502;

uses
  Sysutils;

const
  MAX = 3300;

var
  f: text;
  i: integer;

begin
  Assign(f,'Test502a.dpr');
  Rewrite(f);

Writeln(f,'{$A+,B-,C-,D+,E-,F-,G+,H+,I+,J+,K-,L+,M-,N+,O-,P+,Q-,R+,S-,T-,U-,
V+,W+,X+,Y-,Z1}');
  Writeln(f,'program Test502a;');
  Writeln(f,'uses Forms;');
  Writeln(f,'var s: array [1..',MAX,'] of string;');
  Writeln(f,'begin');
  for i := 1 to MAX do
    Writeln(f,'  s[',i,'] := ''line ',i,''';');
  Writeln(f,'end.');
  Close(f);
end.
--------------- cut here ---------------
It will generate a test program, test.dpr, with a bunch of string assignment statements in the form of
  s[3282] := 'line 3282';
  s[3283] := 'line 3283';
  s[3284] := 'line 3284';
  s[3285] := 'line 3285';
  s[3286] := 'line 3286';
  s[3287] := 'line 3287';
  s[3288] := 'line 3288';
  s[3289] := 'line 3289';
Open Test502a.dpr in Delphi, compile and run. You'll get an Access Violation exception. In Delphi 3.02 exception occurs on line "s[3298] := 'line 3298';", in Delphi 4.0 + Update 1 it occures on the next line (s[3299] := ...). A quick glance at code generated shows why (this example is from D 3.02):
  s[3297] := 'line 3297';

    mov eax,$0045cb64
    mov edx,$00457830
    call @LStrAsg

  s[3298] := 'line 3298';

    mov eax,$0045cb68
    mov edx,$00447833  ; Here lies the bug!
    call @LStrAsg
The address, moved into edx should be $00457833, which is exactly $10000 (64 kb!) off. Looks like in the depth of the Delphi compiler/linker there is still some win16-pointer-related arithmetic which is not completely bulletproof.

Comment from Tor-Arne Riksheim:
I ran the test, and found that the error doesn't happen if the stringtable is made of ShortStrings.

Jordan Russell:
In Delphi 6.0, the compiler now displays this error message: "Too many local constants. Use shorter procedures."

User-contributed comments
Jorge Rojas
23 Mar 2001  10:11 AM GMT
Work around:
Try breaking long linear code like that on procedures, Seems to work.
Latest update of this entry: 2001-06-19

Post a comment on this bug


Index page
Delphi Bug List home page
The Delphi Bug Lists are presently maintained by Jordan Russell, who has taken over this task from Reinier Sterkenburg since August 2000.
All feedback is appreciated. See also the feedback section of the Delphi Bug List home page.