[fpc-pascal] Examples of FPC good practice

paul at codecompiler.com paul at codecompiler.com
Thu Sep 15 08:54:23 CEST 2005


I would like to point out some places where I think FPC has done an
excellent job of continuing the spirit of what Pascal was and should
be: a programming language which provides better "safety" in the
creation of computer programs.  By "safety" I mean that more potential
errors are either prevented or cannot occur in the first place.  Buffer
overflows, spam, viruses are the results of the lack or inadequacy of
safety in program development.  

I hadn't even thought about it until now, but a Pascal program that is
compiled with run-time checks (which is the default) will not have a
buffer overflow problem, because attempting to access an array outside
of the appropriate bounds isn't just a bad practice, it causes a
program error and unless it's in a TRY/FINALLY block, the program will
crash instead of doing something it shouldn't.

Now, there are ways to get around this, but you would have to be aware
that is exactly what you're trying to do.  

Here is an example of one really good feature:

In the AAEC Pascal compiler (which, like FPC is written to be
self-compilable), it defines a construct for defining relocations of
addresses.   (Numbers on each line are from the source.)  These are
defined as follows:

TYPE
(*0221*)RLDDATA = RECORD
(*0222*)            RELPOS : INTEGER;
(*0223*)            FLAGADDRESS : INTEGER
(*0224*)          END;
(*0225*)
(*0226*)
(*0227*)RLDBUF = RECORD
(*0228*)           PRELUDE : ALFA;
(*0229*)           BYTES   : INTEGER;
(*0230*)           DUMMY   : PACKED ARRAY (. 1..4 .) OF CHAR;
(*0231*)           RLDITEMS: ARRAY (. 1..7 .) OF RLDDATA;
(*0232*)           SEQNOS  : ALFA
(*0233*)         END;

VAR
(*0401*)RLD : RLDBUF;       (* MAIN RLD BUFFER *)


Now, to set the value it uses a 'value' clause, like this:

(*0468*)VALUE 
(*0537*)RLD := (# ' RLD    ',0,'    ',0,0,0,0,0,0,0,0,0,0,0,0,0,0,'     
  '#);

FPC requires the setting of the value to be done like this:

(*0468*)CONST
(*0537*)  RLD : RLDBUF =
             (prelude:' RLD    ';bytes: 0; dummy: '    ';
             rlditems:((relpos: 0;flagaddress: 0),
                       (relpos: 0;flagaddress: 0),
                       (relpos: 0;flagaddress: 0),
                       (relpos: 0;flagaddress: 0),
                       (relpos: 0;flagaddress: 0),
                       (relpos: 0;flagaddress: 0),
                       (relpos: 0;flagaddress: 0));
                       seqnos:'        ');

(I've spread the one line across many lines to improve readability.) 
Here, what each value is becomes mandatorily documented, making a big
win for readability and correctness, since you can't accidentally
assign a value wrongly; you have to explicitly name the fields of the
record to assign values to them.  

One thing I do like AAEC doing is the use of a 'VALUE' clause in order
to separate immutable constants versus compile-time initialized data. 
I also like the use of := to indicate it is an assignment, and the use
of (# and #) to make explicit that this is a compile-time
initialization of a variable.  (The (# and #) construct is only used
for value entries.)  This might be something to consider as an option.

So each has some potential advantages.  FPC does what it does to be
compatible with Turbo Pascal.   I personally like the way FPC requires
explicit naming of record fields for assignment, I think it's a good
idea.

Paul Robinson
Robinson Telephone Company
Arlington VA





More information about the fpc-pascal mailing list