Having got 20011123 to compile, I found three differences in the compiler from our previous gpc version 20010604. It objected in two different units to code using a GOTO with the error message: " Label '1' used before containing binding contour'.
The code looks correct and compiles and executes properly with the previous version. Is this a known problem as it looks as though it should be fairly easy to produce a test case if required. However the problem is easily worked around.
Secondly it picked up a number of occurrences of incorrect code of the form St[9]:=Chr(65)+Random(26) that had been accepted by the previous version; so that is progress.
My main problem is that the packing of records appears to have changed. For instance a record of the form
TCompR=Packed Record AName:String(49); AClass:1..40; Awel:Set of 1..120; RLate,RTime:Integer; End;
has the same size as previously (as reported by sizeof) but when using this record to read from a file written by code compiled with our previous version of the compiler gives nonsense values for AClass and Awel. I can work around this particular problem by changing the definition of AClass to Byte but sadly our code has a great many packed records (because it was originally written a long time ago when storage was more precious) but making all the files backwards compatible is not going to be trivial. So two questions: Is there any switch that will restore the previous packing behaviour?
Assuming there is not, could someone explain in more detail what has changed and what are the rules governing packing so that I can work out how to redefine each of the affected records.
Martin Liddle wrote:
Having got 20011123 to compile, I found three differences in the compiler from our previous gpc version 20010604. It objected in two different units to code using a GOTO with the error message: " Label '1' used before containing binding contour'.
The code looks correct and compiles and executes properly with the previous version. Is this a known problem as it looks as though it should be fairly easy to produce a test case if required.
So why don't you do this? How can I tell if it's a known problem, or a problem at all, if I don't even know when it happens? Maybe there's a bug in your code that previous GPC versions didn't notice, maybe it's a GPC bug, who knows?
Secondly it picked up a number of occurrences of incorrect code of the form St[9]:=Chr(65)+Random(26) that had been accepted by the previous version; so that is progress.
At least. ;-)
My main problem is that the packing of records appears to have changed. For instance a record of the form
TCompR=Packed Record AName:String(49); AClass:1..40; Awel:Set of 1..120; RLate,RTime:Integer; End;
has the same size as previously (as reported by sizeof) but when using this record to read from a file written by code compiled with our previous version of the compiler gives nonsense values for AClass and Awel. I can work around this particular problem by changing the definition of AClass to Byte but sadly our code has a great many packed records (because it was originally written a long time ago when storage was more precious) but making all the files backwards compatible is not going to be trivial. So two questions: Is there any switch that will restore the previous packing behaviour?
Assuming there is not, could someone explain in more detail what has changed and what are the rules governing packing so that I can work out how to redefine each of the affected records.
I've changed a number of things WRT sets. Maybe one of them is responsible for what you observe, maybe not ...
If you want more help on this, please provide specific information such as a test program, a test file that the program reads, a description of the values expected and observed, and all the usual stuff.
Please remember that we're doing this for free, and I don't want to waste my time guessing what you did.
Alternatively, we can offer you commercial support that allows us to devote more time to solving your particular problem. If you are interested, please contact info@g-n-u.de.
Frank
In article 200111300132.CAA14769@goedel.fjf.gnu.de, Frank Heckenbach frank@g-n-u.de writes
The code looks correct and compiles and executes properly with the previous version. Is this a known problem as it looks as though it should be fairly easy to produce a test case if required.
So why don't you do this? How can I tell if it's a known problem, or a problem at all, if I don't even know when it happens? Maybe there's a bug in your code that previous GPC versions didn't notice, maybe it's a GPC bug, who knows?
Frank
I seem to have hit a raw nerve and I apologise if my posting was inappropriate. I didn't want to waste the bandwidth of everybody on the list by posting a listing about a known problem. Here is the simplest program I can devise that shows the problem. It compiles and executes with version 20010604 but fails to compile with version 20011123 with the error message "label '1' used before containing binding contour". Please note that there is a trivial work around for the real code so this is a very low priority problem for us.
Program TCS_Test1; Label 1;
Var Line:String(255); Fseed:Text;
Begin Line:='ABC'; If Line[1] <>'C' then Goto 1; Reset(FSeed,Line+'seed'); 1: End.
My main problem is that the packing of records appears to have changed.
I've changed a number of things WRT sets. Maybe one of them is responsible for what you observe, maybe not ...
OK. I'm working on a pair of test programs to demonstrate the behaviour I see. My initial efforts work perfectly (i.e. don't show the problem) so I obviously haven't got to grips with the real problem yet.
Please remember that we're doing this for free, and I don't want to waste my time guessing what you did.
I understand this and I have tried in the past to be appreciative of your efforts and the efforts of others who contribute. I was expecting to be told to RTFM but hoped that somebody could point out the appropriate section of the FM.
Alternatively, we can offer you commercial support that allows us to devote more time to solving your particular problem. If you are interested, please contact info@g-n-u.de.
We will certainly consider commercial support in the future.
In article 0kxzRuCDU3B8Ew1j@tcs02.demon.co.uk, Martin Liddle martin@tcs02.demon.co.uk writes
In article 200111300132.CAA14769@goedel.fjf.gnu.de, Frank Heckenbach frank@g-n-u.de writes
My main problem is that the packing of records appears to have changed.
I've changed a number of things WRT sets. Maybe one of them is responsible for what you observe, maybe not ...
OK. I'm working on a pair of test programs to demonstrate the behaviour I see. My initial efforts work perfectly (i.e. don't show the problem) so I obviously haven't got to grips with the real problem yet.
Sorry to take so long but its taken me all day to work exactly what is triggering the problem.
The first program simply writes a data file and performs as expected. The second program reads the data back. Under 20010604 it performs as expected. Under 20011123 the values for class are 513, 1026 and 2051. For the problem to be shown then it is necessary for the definitions to be in a separate unit. If the definitions and procedures are in the main body of the program then everything works correctly.
=================================
Program TCS_Test2; Type TCompr=Packed Record AClass:1..40; Awel:Set of 1..120; End; Var J:Integer; AFile:File [1..3] of TCompr; Begin Rewrite(AFile,'TCS_test'); For J:=1 to 3 Do Begin SeekWrite(AFile,J); With Afile^ Do Begin AClass:=J; Awel:=[J]; End; Put(AFile); End; Close(AFile); End.
========================================== Program TCS_Test3;
Uses TCS_test3U;
Begin Reset(AFile,'TCS_test'); For J:=1 to 3 Do Begin With Afile^ Do Begin Write(' Class: ',AClass:2,' Awel: '); For K:=1 To 40 Do If K in Awel then Write(K,' '); Writeln; End; Get(AFile); End; Close(AFile); End.
===============================================
Unit TCS_test3u;
Interface
Type TCompr=Packed Record AClass:1..40; Awel:Set of 1..120; End; Var J,K:Integer; AFile:File [1..3] of TCompr;
Implementation
End.
Martin Liddle wrote:
The first program simply writes a data file and performs as expected. The second program reads the data back. Under 20010604 it performs as expected. Under 20011123 the values for class are 513, 1026 and 2051. For the problem to be shown then it is necessary for the definitions to be in a separate unit. If the definitions and procedures are in the main body of the program then everything works correctly.
Again, the test program was quite necessary. The bug was in the interface (GPI) mechanism, and just happened to affect packed records (and possibly other things as well, though I haven't observed any). (martin2a.pas, and martin2b.pas for an even simpler example that showed the bug)
Patch attached (though it was made against otherwise modified sources; if you can't apply it, you'll have to wait for Peter's next upload).
Frank
In article 200112030149.CAA20486@goedel.fjf.gnu.de, Frank Heckenbach frank@g-n-u.de writes
Again, the test program was quite necessary. The bug was in the interface (GPI) mechanism, and just happened to affect packed records (and possibly other things as well, though I haven't observed any). (martin2a.pas, and martin2b.pas for an even simpler example that showed the bug)
Patch attached (though it was made against otherwise modified sources; if you can't apply it, you'll have to wait for Peter's next upload).
The patch worked with one minor problem. A line in todo.texi was inserted one line too high up in the file and stopped the build. A bit of trial and error soon sorted out the problem. Also I am a bit puzzled that the build also stopped, complaining that bison wasn't installed (which was true) but it hadn't been required previously. Installing bison fixed the problem. I am very pleased to report that the fix works both for my test program and at a very preliminary inspection for my application :-) Also the patched compiler caught an attempt (which had previously been missed) to assign a constant value to a subrange outside the limits of the subrange :-)
Thank you once again for your usual prompt and extremely helpful responses to our problems. We do appreciate your efforts even if we sometimes forget to say so.
I have observed one more, possibly cosmetic, problem which I will investigate and attempt to produce a test program to demonstrate.
Martin Liddle wrote:
In article 200112030149.CAA20486@goedel.fjf.gnu.de, Frank Heckenbach frank@g-n-u.de writes
Again, the test program was quite necessary. The bug was in the interface (GPI) mechanism, and just happened to affect packed records (and possibly other things as well, though I haven't observed any). (martin2a.pas, and martin2b.pas for an even simpler example that showed the bug)
Patch attached (though it was made against otherwise modified sources; if you can't apply it, you'll have to wait for Peter's next upload).
Also I am a bit puzzled that the build also stopped, complaining that bison wasn't installed (which was true) but it hadn't been required previously.
The bison generated files (parse.[ch]) are supplied with source distributions (not CVS). My patched changed the source (parse.y), so bison was needed to regenerate them (I could have sent patched for them as well, of course, but I didn't think of it, since I usually only make patches of the real sources.)
BTW, this part of the patch only dealt with the `class' issue (another thread), so it would have been safe to skip it (touch parse.[ch]).
However, testing martin2a.pas on Sparc and MIPS revealed another problem. These processors (as typical for RISCs) have strict alignment requirements for word accesses, e.g., they can't read 32-bit values from addresses not divisible by 4. The set field of the (now really) packed record is not at an aligned address, and the RTS set routines do word access.
I see the following possible solutions:
- Always align sets in packed records. This would break your binary files again.
- Do it only on platforms with alignment requirements. This would increase the binary file incompatibilty between platforms. They're now not fully compatible due to endianness, but such a change would add another important issue which would not be easy to work around (i.e., it would be almost impossible to use such binary files in a platform-independent way).
- Change the RTS set routines to byte accesses. That's easy to do (and has been discussed here some months ago), but would decrease the efficiency.
- Let the RTS set routines check (on each invocation) if access is aligned. If not (and the platform requires it), use special code (like for packed arrays); otherwise use the faster word access.
Frank
In article 200112040107.CAA20666@goedel.fjf.gnu.de, Frank Heckenbach frank@g-n-u.de writes
The bison generated files (parse.[ch]) are supplied with source distributions (not CVS). My patched changed the source (parse.y), so bison was needed to regenerate them (I could have sent patched for them as well, of course, but I didn't think of it, since I usually only make patches of the real sources.)
Thanks for explaining. It wasn't a problem, just a curiosity.
However, testing martin2a.pas on Sparc and MIPS revealed another problem. These processors (as typical for RISCs) have strict alignment requirements for word accesses, e.g., they can't read 32-bit values from addresses not divisible by 4. The set field of the (now really) packed record is not at an aligned address, and the RTS set routines do word access.
I see the following possible solutions:
- Always align sets in packed records. This would break your binary
files again.
Maintaining backwards file compatibility is nice for us but not essential although if it is going to change then it would be nice if any other imminent changes were done at the same time.
- Do it only on platforms with alignment requirements. This would
increase the binary file incompatibilty between platforms. They're now not fully compatible due to endianness, but such a change would add another important issue which would not be easy to work around (i.e., it would be almost impossible to use such binary files in a platform-independent way).
Yes we have struggled with those sort of issues in the past and it does get messy.
- Change the RTS set routines to byte accesses. That's easy to do
(and has been discussed here some months ago), but would decrease the efficiency.
Efficiency is not a big issue for us. Our code would just about run on a Z80 using UCSD interpreted p-code and ran quite reasonably with critical sections native coded. On todays processors we struggle to get the processor usage above 5% when supporting 50 users. However I appreciate that efficiency may be very important to other users.
- Let the RTS set routines check (on each invocation) if access is
aligned. If not (and the platform requires it), use special code (like for packed arrays); otherwise use the faster word access.
This is presumably the most difficult solution. How many places in the RTS would require changing?
Summary. We are happy to go along with the majority view but would ask that as many changes as possible that affect binary compatibility are made together rather than in a series of small changes across a number of versions.
On Tue, 4 Dec 2001, Frank Heckenbach wrote:
However, testing martin2a.pas on Sparc and MIPS revealed another problem. These processors (as typical for RISCs) have strict alignment requirements for word accesses, e.g., they can't read 32-bit values from addresses not divisible by 4. The set field of the (now really) packed record is not at an aligned address, and the RTS set routines do word access.
I see the following possible solutions:
Always align sets in packed records. This would break your binary files again.
Do it only on platforms with alignment requirements. This would increase the binary file incompatibilty between platforms. They're now not fully compatible due to endianness, but such a change would add another important issue which would not be easy to work around (i.e., it would be almost impossible to use such binary files in a platform-independent way).
Change the RTS set routines to byte accesses. That's easy to do (and has been discussed here some months ago), but would decrease the efficiency.
Let the RTS set routines check (on each invocation) if access is aligned. If not (and the platform requires it), use special code (like for packed arrays); otherwise use the faster word access.
Mixed approach:
- Do some of this work at compile time - since at compile time from record structure can be determined whether unaligned access can happen. This means that
one has two versions of RTS set routines - one (faster) for align-safe access and other, with checks deferred to runtime
If set is packed accidentaly at 32-bit word boundary, it's safe to do a compile time check - and it's programmers responsability to organize data efficiently.
(You will probably remember that I liked two versions of code even before, when we discussed runtime range checks).
Mirsad
-- This message has been made up using recycled ideas and language constructs. No plant or animal has been injured in process of making this message.
In article TkL6xoBnC3C8EwoC@tcs02.demon.co.uk, Martin Liddle martin@tcs02.demon.co.uk writes
I have observed one more, possibly cosmetic, problem which I will investigate and attempt to produce a test program to demonstrate.
I have now investigated this problem. The compiler was reporting "warning: comparison is always 'True' due to the limited range of data type" for an expression such as:
If (Check[Control].ChecH<24) and (Check[Control].ChecH>=0) then
where ChecH is a field in a packed record defined as follows:
TAudit1=Packed Record ChecH:0..47; ChecM:0..60; .... End;
This problem was present in both the 20010604 and 20011123 versions of the compiler. I am pleased to say that using the patched version of the 20011123 compiler has eliminated the spurious warning:-) Thank you Frank.
Martin Liddle wrote:
In article TkL6xoBnC3C8EwoC@tcs02.demon.co.uk, Martin Liddle martin@tcs02.demon.co.uk writes
I have observed one more, possibly cosmetic, problem which I will investigate and attempt to produce a test program to demonstrate.
I have now investigated this problem. The compiler was reporting "warning: comparison is always 'True' due to the limited range of data type" for an expression such as:
If (Check[Control].ChecH<24) and (Check[Control].ChecH>=0) then
where ChecH is a field in a packed record defined as follows:
TAudit1=Packed Record ChecH:0..47; ChecM:0..60; .... End;
This problem was present in both the 20010604 and 20011123 versions of the compiler. I am pleased to say that using the patched version of the 20011123 compiler has eliminated the spurious warning:-) Thank you
I suppose the packed record was declared in a unit as well (otherwise I'd be surprised if my change affected this case).
However, the warning was actually not spurious since `CheckH >= 0' is indeed always True. But I'm not too worried, since we haven't implemented such warnings rigorously (only in some special cases, mostly inherited from C). But we may do this in the future, and then you'll get this warning again. Be prepared. ;-)
Frank
Martin Liddle wrote:
In article 200111300132.CAA14769@goedel.fjf.gnu.de, Frank Heckenbach frank@g-n-u.de writes
The code looks correct and compiles and executes properly with the previous version. Is this a known problem as it looks as though it should be fairly easy to produce a test case if required.
So why don't you do this? How can I tell if it's a known problem, or a problem at all, if I don't even know when it happens? Maybe there's a bug in your code that previous GPC versions didn't notice, maybe it's a GPC bug, who knows?
Frank
I seem to have hit a raw nerve and I apologise if my posting was inappropriate. I didn't want to waste the bandwidth of everybody on the list by posting a listing about a known problem. Here is the simplest program I can devise that shows the problem. It compiles and executes with version 20010604 but fails to compile with version 20011123 with the error message "label '1' used before containing binding contour". Please note that there is a trivial work around for the real code so this is a very low priority problem for us.
Program TCS_Test1; Label 1;
Var Line:String(255); Fseed:Text;
Begin Line:='ABC'; If Line[1] <>'C' then Goto 1; Reset(FSeed,Line+'seed'); 1: End.
Providing the test program (martin1.pas) was important. The really guilty one is the string addition. That's a known problem and has surfaced in other forms recently. I'm a bit surprised how often it appears recently, since AFAIK not much has changed in this area for quite some time. But bugs have lives of their own ...
Probably only Peter can fix this bug. You might want to get in direct contact with him (e.g., via info@g-n-u.de) if you need to know when he has the time to fix it.
Work-arounds for this case would be to encapsulate the problematic statement (Reset) in an additional `begin'/`end' block, or move it to a subroutine.
Frank