Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2005-08

Constant arrays sometimes produce incorrect data tables

3 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

David Butler

Hi all

I picked up this weird code generation problem (it was also present in 2.0.0). I reported it as bug 4277 today. Unfortunately I can only reproduce it in a specific context, so please e-mail me for the unit.

The problem is when you define an array of constant strings.

For example:

const
  RFCMonthNames : Array[1..12] of String = (
    'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
    'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');

is usually assembled as something like:

TC_P$TESTARRAY_RFCMONTHNAMES
DD _$PROGRAM$_L4, _$PROGRAM$_L5, _$PROGRAM$_L6, _$PROGRAM$_L7, ...... DD -1,3
_$PROGRAM$_L4: DB "Jan",0 DD -1,3
_$PROGRAM$_L5: DB "Feb",0 DD -1,3
....

which is correct, but the exact same code (in a different unit) is compiled differently, causing access violations when accessed:

TC_CDATETIME_RFCMONTHNAMES
DD _$CDATETIME$_L2046
DD -1,3
_$CDATETIME$_L2046:
DB "Jan",0
DD _$CDATETIME$_L2047
DD -1,3
_$CDATETIME$_L2047:
DB "Feb",0
DD _$CDATETIME$_L2048
DD -1,3
_$CDATETIME$_L2048:
DB "Mar",0
DD _$CDATETIME$_L2049
DD -1,3
_$CDATETIME$_L2049:
DB "Apr",0
........

Regards
David

Reply by email

David Butler
to Anton Tichawa: There are two kinds of strings, shortstrings (max. 256 bytes) and ansistrings (any…

Hi Anton

Thanks for the suggestion.

I checked this by changing String to AnsiString, both in the declaration and where the array is accessed, but it still compiles differently in the two units.

It seems that where the usual pattern is to store the table as "Ptr, Ptr, Ptr, ..., Value, Value, Value, ...", in this case it stored as "Ptr, Value, Ptr, Value, Ptr, Value, ...".

Regards
David

you wrote 44 lines
>const > RFCMonthNames : Array[1..12] of String = ( > 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', > 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'); > >is usually assembled as something like: > >TC_P$TESTARRAY_RFCMONTHNAMES >DD _$PROGRAM$_L4, _$PROGRAM$_L5, _$PROGRAM$_L6, _$PROGRAM$_L7, ...... >DD -1,3 >_$PROGRAM$_L4: DB "Jan",0 DD -1,3 >_$PROGRAM$_L5: DB "Feb",0 DD -1,3 >.... > >which is correct, but the exact same code (in a different unit) is >compiled differently, causing access violations when accessed: > >TC_CDATETIME_RFCMONTHNAMES >DD _$CDATETIME$_L2046 >DD -1,3 >_$CDATETIME$_L2046: >DB "Jan",0 >DD _$CDATETIME$_L2047 >DD -1,3 >_$CDATETIME$_L2047: >DB "Feb",0 >DD _$CDATETIME$_L2048 >DD -1,3 >_$CDATETIME$_L2048: >DB "Mar",0 >DD _$CDATETIME$_L2049 >DD -1,3 >_$CDATETIME$_L2049: >DB "Apr",0 >........ There are two kinds of strings, shortstrings (max. 256 bytes) and ansistrings (any length, allocated on the heap). May be they're mixed, because the declaration "string" might use a shortstring in one unit, an ansistring in another, depending on compiler switches like "$H" or "$LONGSTRINGS". Such mixing would very likely cause access violations. Try e. g. to change all declarations to "shortstring", which is enough for short month names.

Reply by email

Anton Tichawa
to David Butler: Hi all I picked up this weird code generation problem (it was also present in 2.0.0). I…
David Butler wrote 57 lines
Hi all I picked up this weird code generation problem (it was also present in 2.0.0). I reported it as bug 4277 today. Unfortunately I can only reproduce it in a specific context, so please e-mail me for the unit. The problem is when you define an array of constant strings. For example: const RFCMonthNames : Array[1..12] of String = ( 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'); is usually assembled as something like: TC_P$TESTARRAY_RFCMONTHNAMES DD _$PROGRAM$_L4, _$PROGRAM$_L5, _$PROGRAM$_L6, _$PROGRAM$_L7, ...... DD -1,3 _$PROGRAM$_L4: DB "Jan",0 DD -1,3 _$PROGRAM$_L5: DB "Feb",0 DD -1,3 .... which is correct, but the exact same code (in a different unit) is compiled differently, causing access violations when accessed: TC_CDATETIME_RFCMONTHNAMES DD _$CDATETIME$_L2046 DD -1,3 _$CDATETIME$_L2046: DB "Jan",0 DD _$CDATETIME$_L2047 DD -1,3 _$CDATETIME$_L2047: DB "Feb",0 DD _$CDATETIME$_L2048 DD -1,3 _$CDATETIME$_L2048: DB "Mar",0 DD _$CDATETIME$_L2049 DD -1,3 _$CDATETIME$_L2049: DB "Apr",0 ........ Regards David _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

There are two kinds of strings, shortstrings (max. 256 bytes) and ansistrings (any length, allocated on the heap). May be they're mixed, because the declaration "string" might use a shortstring in one unit, an ansistring in another, depending on compiler switches like "$H" or "$LONGSTRINGS".
Such mixing would very likely cause access violations. Try e. g. to change all declarations to "shortstring", which is enough for short month names.

hth,

Anton.

Reply by email