Hi Frank
I thought the problem with packed records was fixed in 20030830 - but this program:
program packer; uses strings; Type foo = packed record sig : array [ 0..3 ] OF char; end;
Var f : foo; Begin strcopy (f.sig, 'OK'); End.
produces this compiler error: packer.pas: In main program: packer.pas:10: cannot take address of packed record field `sig'
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~african_chief/
Prof A Olowofoyeku (The African Chief) wrote:
Hi Frank
I thought the problem with packed records was fixed in 20030830 - but this program:
program packer; uses strings; Type foo = packed record sig : array [ 0..3 ] OF char; end;
Var f : foo; Begin strcopy (f.sig, 'OK'); End.
produces this compiler error: packer.pas: In main program: packer.pas:10: cannot take address of packed record field `sig'
The error seems correct. Converting an array of Char to CString means taking the address.
Frank
On 13 Dec 2003 at 17:34, Frank Heckenbach wrote: [...]
Type foo = packed record sig : array [ 0..3 ] OF char; end;
Var f : foo; Begin strcopy (f.sig, 'OK'); End.
produces this compiler error: packer.pas: In main program: packer.pas:10: cannot take address of packed record field `sig'
The error seems correct. Converting an array of Char to CString means taking the address.
[...] Hmm ... This has just broken my unzip sources. The record has to be packed, and I have to do things (e.g., as above) with the signature field. I guess I either have to convert all the code so that it will compile with "--delphi", or find some other hack to circumvent this :/ Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~african_chief/
Prof A Olowofoyeku (The African Chief) wrote:
On 13 Dec 2003 at 17:34, Frank Heckenbach wrote: [...]
produces this compiler error: packer.pas: In main program: packer.pas:10: cannot take address of packed record field `sig'
The error seems correct. Converting an array of Char to CString means taking the address.
[...] Hmm ... This has just broken my unzip sources. The record has to be packed, and I have to do things (e.g., as above) with the signature field. I guess I either have to convert all the code so that it will compile with "--delphi", or find some other hack to circumvent this :/
I know that the Pascal Standard forbids taking the address of a field in a packed record. However, from a practical point of view I have always felt this is a rather clumsy restriction, unless of course the address is not byte aligned. Some Pascal implementations take the pragmatic course and allow taking the address of a field in a packed record if it is byte aligned. Is there any compelling reason why we should not allow this, except in Standard or Extended Pascal mode ?
Regards,
Adriaan van Os
On 13 Dec 2003 at 22:53, Adriaan van Os wrote:
[...]
I know that the Pascal Standard forbids taking the address of a field in a packed record. However, from a practical point of view I have always felt this is a rather clumsy restriction, unless of course the address is not byte aligned. Some Pascal implementations take the pragmatic course and allow taking the address of a field in a packed record if it is byte aligned. Is there any compelling reason why we should not allow this, except in Standard or Extended Pascal mode ?
It was allowed by GPC in the past. It would certainly make my life a lot easier if it was allowed again if not in one of the ISO modes. I am now faced with making signficant amendments to a few projects because of this one thing :(
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~african_chief/
Adriaan van Os wrote:
I know that the Pascal Standard forbids taking the address of a field in a packed record. However, from a practical point of view I have always felt this is a rather clumsy restriction, unless of course the address is not byte aligned. Some Pascal implementations take the pragmatic course and allow taking the address of a field in a packed record if it is byte aligned. Is there any compelling reason why we should not allow this, except in Standard or Extended Pascal mode ?
Address have to be properly aligned. Unaligned reference may couse crash (some RISC machines, notably SPARC and AFAIK early PPC) or data corruption (ARM). If the backend belives that data is aligned it may generate fullword access even for characters (when copying arrays). So GPC would have to duplicate backend checks and accept/reject program depending on target characteristics. ATM I can not say how hard would be to implement such behaviour, but the end result look really like a loss:
1) program correctness would depend on rather on rather complex platform dependent alignment rules
2) program portability would decline
3) small modifications to data layout would convert valid program into invalid one
IMHO it much better to restructure the program. For example just use auxilary variable and copy the field (or pack/unpack the whole record) when needed.
On 14 Dec 2003 at 0:56, Waldek Hebisch wrote:
[...]
Address have to be properly aligned. Unaligned reference may couse crash (some RISC machines, notably SPARC and AFAIK early PPC) or data corruption (ARM). If the backend belives that data is aligned it may generate fullword access even for characters (when copying arrays). So GPC would have to duplicate backend checks and accept/reject program depending on target characteristics. ATM I can not say how hard would be to implement such behaviour, but the end result look really like a loss:
Previous versions of GPC permitted this, and the code worked correctly both on Sparc (Solaris) and x86 (Windows and Linux). So it would seem that all that needs to happen is for what was done in recent times to be undone when not using any of the ISO standards.
program correctness would depend on rather on rather complex platform dependent alignment rules
program portability would decline
small modifications to data layout would convert valid program into invalid one
I am not sure about any of these. But what has happened is that the new restrictions have broken code that has existed and worked happily under GPC for a very long time.
IMHO it much better to restructure the program. For example just use auxilary variable
That would be quite tedious, but it might well be what I will have to do (or use older versions of GPC for the affected code).
and copy the field (or pack/unpack the whole record) when needed.
I am not sure how to do that ...
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~african_chief/
Prof A Olowofoyeku wrote:
On 14 Dec 2003 at 0:56, Waldek Hebisch wrote:
[...]
Address have to be properly aligned. Unaligned reference may couse crash (some RISC machines, notably SPARC and AFAIK early PPC) or data corruption (ARM). If the backend belives that data is aligned it may generate fullword access even for characters (when copying arrays). So GPC would have to duplicate backend checks and accept/reject program depending on target characteristics. ATM I can not say how hard would be to implement such behaviour, but the end result look really like a loss:
Previous versions of GPC permitted this, and the code worked correctly both on Sparc (Solaris) and x86 (Windows and Linux). So it would seem that all that needs to happen is for what was done in recent times to be undone when not using any of the ISO standards.
Maybe I overreacted, but recently I fixed an ARM bug, when backend lost track of alignment... However, your code may be fine but similar code may fail (if a field requires better then byte alignment and happens to be misaligned). I have not looked at relevant code in GPC (Frank did the change) but I suspect that GPC just happily generated wrong code (in some cases). Pascal philosophy (adapted by most modern languages) is to catch problems at compile time. It is hard to be sure that a problem will appear, so the language forbids anything which _may_ be incorrect.
program correctness would depend on rather on rather complex platform dependent alignment rules
program portability would decline
small modifications to data layout would convert valid program into invalid one
I am not sure about any of these. But what has happened is that the new restrictions have broken code that has existed and worked happily under GPC for a very long time.
Well, I frequently have the same feeling. But I also keep finding blatant errors in code that "worked happily" for years. So I am very sceptical about changes that reduce error checking in the compiler. IMHO if reduced error checking is needed it should be localised, so that other parts of the program (or other programs) still are checked. One possibility could be "customisable" (skinable??) language -- where the user would specify exactly (say, in a config file) which constucts are allowed. But that would complicate GPC quite a lot...
IMHO it much better to restructure the program. For example just use auxilary variable
That would be quite tedious, but it might well be what I will have to do (or use older versions of GPC for the affected code).
I corrected similar problem (type mismatch between record field and a var parameter) in Stanford Pascal (~ 10000 lines of code, tens of calls to correct). The correction is not very nice, but after about 1 hour I was done. In your case it would look like: { In declaration section } Type tsig = array [ 0..3 ] OF Char; foo = packed record sig : tsig; end;
{ At apropriate scope} Var foo_aux : tsig; Var f : foo;
begin foo_aux := f.sig; StrCopy (foo_aux, 'OK'); f.sig := foo_aux end.
(of course for `StrCopy' there is no need for the first assignment, but I want to show general case). Tedious -- yes, but can be done quickly.
and copy the field (or pack/unpack the whole record) when needed.
I am not sure how to do that ...
I basically challenge your need to have a packed record. You can copy the whole record to an unpacked one (tedious if you have many fields but may be less work then previous approach) and back when needed.
If my wild guess is correct you need packed record to match file header. Then the best way may be to copy it to unpacked record on reading file and copy to packed one on writing.
Finally, if you really want quick&dirty solution the following seem to do what you want:
program packer; uses Strings; Type {$pack-struct, maximum-field-alignment 8} foo = record sig : array [ 0..3 ] OF Char; end; {$no-pack-struct, maximum-field-alignment 0}
Var f : foo; begin StrCopy (f.sig, 'OK'); writeln (f.sig[0], f.sig[1]) end.
I'm a bit injured and I can only type with one hand, so I'll pprobably be quite silent for 1-2 weeks.
I mostly agree with Waldek.
Waldek Hebisch wrote:
Well, I frequently have the same feeling. But I also keep finding blatant errors in code that "worked happily" for years. So I am very sceptical about changes that reduce error checking in the compiler. IMHO if reduced error checking is needed it should be localised, so that other parts of the program (or other programs) still are checked. One possibility could be "customisable" (skinable??) language -- where the user would specify exactly (say, in a config file) which constucts are allowed. But that would complicate GPC quite a lot...
More compiler directives ... but IHMO only if it can be reasonably supported (i.e., if taking the address at least work everywhere which doesn't seem to be the case).
I corrected similar problem (type mismatch between record field and a var parameter) in Stanford Pascal (~ 10000 lines of code, tens of calls to correct). The correction is not very nice, but after about 1 hour I was done. In your case it would look like: { In declaration section } Type tsig = array [ 0..3 ] OF Char; foo = packed record sig : tsig; end;
{ At apropriate scope} Var foo_aux : tsig; Var f : foo;
begin foo_aux := f.sig; StrCopy (foo_aux, 'OK'); f.sig := foo_aux end.
(of course for `StrCopy' there is no need for the first assignment, but I want to show general case). Tedious -- yes, but can be done quickly.
Perhaps you can just treat the array as a Pascal string (almost standard, since index isn't 1 based, but GPC allows it):
f.sig := 'OK';
If you need CString semantics, add #0 explicitly. Depending on what you actually do with it, this might work ...
If my wild guess is correct you need packed record to match file header. Then the best way may be to copy it to unpacked record on reading file and copy to packed one on writing.
Or read header in parts (packed, then unpacked for this one -- I think we can guarantee that un-/packed array of char have the same layout -- otherwise I think many things would break).
Finally, if you really want quick&dirty solution the following seem to do what you want:
program packer; uses Strings; Type {$pack-struct, maximum-field-alignment 8} foo = record sig : array [ 0..3 ] OF Char; end; {$no-pack-struct, maximum-field-alignment 0}
Var f : foo; begin StrCopy (f.sig, 'OK'); writeln (f.sig[0], f.sig[1]) end.
Actually this may be closer to the intended meaning, unless really bitfields are used.
Frank
On 14 Dec 2003 at 17:32, Waldek Hebisch wrote: [...]
I basically challenge your need to have a packed record. You can copy the whole record to an unpacked one (tedious if you have many fields but may be less work then previous approach) and back when needed.
If my wild guess is correct you need packed record to match file header.
Yes.
Then the best way may be to copy it to unpacked record on reading file and copy to packed one on writing.
Packing is needed for both reading and writing.
Finally, if you really want quick&dirty solution the following seem to do what you want:
program packer; uses Strings; Type {$pack-struct, maximum-field-alignment 8} foo = record sig : array [ 0..3 ] OF Char; end; {$no-pack-struct, maximum-field-alignment 0}
This solves the problem, and is less tedious to do.
Thanks.
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~african_chief/