Gale Paeper wrote:
Regardless of all the jaw flapping about how one shouldn't use packed data types, the compiler is broke in this area.
To investigate your problem, I tried a few test programs to see what might be wrong. To keep all the various non-standard extensions out of the picture, I compiled in Extended Pascal compliance mode. For the following program:
program CharArrayTest(input, output); {$extended-pascal} type
char_arr = array[1..30] of char;
smallrec = RECORD arr : char_arr; END;
largerec = packed RECORD one_rec : smallrec; many_rec : array[1..5] of smallrec; one_array : char_arr; many_arrays : array[1..5] of char_arr; END;
VAR r: largerec; c, c1: char_arr; aSmallrec: smallrec; aSmallrecArray: array[1..5] of smallrec; i: integer;
begin for i := 1 to 30 do c[i] := chr(i); c1 := c; aSmallrec.arr := c; aSmallrecArray[1].arr := c; end.
I got these totally bogus errors when trying to compile:
CharArrayTest.pas: In main program: CharArrayTest.pas:28: error: using unpacked character arrays as strings
<snip>
The errors are totally bogus because there are abolutely no strings in the program and there is nothing requiring string semantics in the
Agreed. The following patch should fix the problem:
diff -ru tt/gpc-20030830.pp/p/types.c gpc-20030830/p/types.c --- tt/gpc-20030830.pp/p/types.c Wed Aug 13 06:32:06 2003 +++ gpc-20030830/p/types.c Fri Feb 6 05:33:44 2004 @@ -859,9 +859,13 @@ if (TREE_CODE (type) != ARRAY_TYPE || TREE_CODE (TREE_TYPE (type)) != CHAR_TYPE) return 0;
- if (error_flag && !PASCAL_TYPE_PACKED (type)) - chk_dialect ("using unpacked character arrays as strings is", B_D_PASCAL); - + if (!PASCAL_TYPE_PACKED (type)) + { + if (error_flag) + chk_dialect ("using unpacked character arrays as strings is", B_D_PASCAL); + if (co->pascal_dialect & C_E_O_PASCAL) + return 0; + } /* String type low index must be one and nonvarying according to ISO */ if (tree_int_cst_equal (TYPE_MIN_VALUE (TYPE_DOMAIN (type)), integer_one_node)) return 1;
To get around these bogus errors, the following program uses packed to force a string type:
program PackedCharArrayTest(input, output); {$extended-pascal} type
char_arr = packed array[1..30] of char;
smallrec = RECORD arr : char_arr; END;
largerec = packed RECORD one_rec : smallrec; many_rec : array[1..5] of smallrec; one_array : char_arr; many_arrays : array[1..5] of char_arr; END;
VAR r: largerec; c, c1: char_arr; aSmallrec: smallrec; aSmallrecArray: array[1..5] of smallrec; i: integer;
begin for i := 1 to 30 do c[i] := chr(i); c1 := c; aSmallrec.arr := c; aSmallrecArray[1].arr := c; r.many_rec[1].arr := c; {compiler error but ISO7185/10206 legal} end.
And I got the same error you've been wrestling with:
PackedCharArrayTest.pas: In main program: PackedCharArrayTest.pas:31: error: cannot take address of packed record field `many_rec'
Again this is a bogus error. The assignment statememt "r.many_rec[1].arr := c;" is fully compliant with all requirements of ISO 7185/10206. The type of "r.many_rec[1].arr" is fixed-string-type with a capacity of 30 and "c" is fixed-string-type with capacity and length both 30 so per ISO 7185/10206 paragraph 6.4.6 f) and ISO 10206 paragraph 6.9.2.2 (6.8.2.2 for ISO 7185) the assignment statement is fully compliant with ISO requirements.
Agreed.
I will note that ISO 7185/10206 puts one extra restriction and ONLY one extra restriction on the usage of a variable of packed type (including string types which are or contain packaged array types). From ISO 10206, paragraph 6.7.3.3:
"An actual variable parameter shall not denote a component of a variable where that variable possesses a type that is designated packed. An actual variable parameter shall not denote a component of a string-type."
However, that requirement doesn't even apply to "r.many_rec[1].arr" since the "arr" field is NOT a packed type compontent. Per ISO 10206. paragraph 6.4.3.1:
"The designation of a structured-type as packed shall affect the representation in data-storage of that structured-type only; i.e., if a component is itself structured, the component's representation in data-storage shall be packed only if the type of the component is designated packed."
In other words, even though the largerec type is designated "packed", the "arr" field isn't a packed field because the smallrec type has NOT been designated "packed".
Hmm, I do not understand what you are trying to argue here. "arr" field is not used as variable parameter, so 6.7.3.3 does not apply. The compiler message is about "many_rec", which is a packed record field (but the compiler does not see that the reference is legal).