[fpc-devel] Portability Standards
DrDiettrich
drdiettrich at compuserve.de
Sat Jan 1 18:31:12 CET 2005
In the meantime I downloaded the Abbrevia package from SourceForge, and
came across several unpleasent constructs. Please let me introduce my
preferred programming model for portable code.
1) Target Dependencies
I don't accept any OS or machine specific conditional compilation in
code, except in dedicated units. In Abbrevia the same fixes occur in
various places in the code, instead of in a dedicated OS specific
procedure. Such a procedure exists, but unfortunately only in the
unpatched form :-(
Also compiler specific conditionals should be used only where absolutely
necessary (local options, syntax differences...).
2) Code Checks
It should be possible to check code for compilation on other platforms.
This requires that target specific code can be compiled on any host,
somehow. Consequently it must be possible to override the compiler
generated symbols that describe the environment.
3) Standard Units
Portable code shall use standard procedures and units for target
specific actions. This requires the definition, implementation, and
consequential use of one or more standard units for:
- Machine specific data types and procedures (endianness...)
- OS specific data types and procedures
- C and POSIX specific data types (for code ported from GNU/C)
Then it should be clear which portable data types and procedures should
be taken from which unit. It also should be easier to determine which
procedures need special considerations in portable code, from the
defined data types and procedures in these units.
It's not necessary that everybody follows these principles, but I will
do so in my own published portable code. Otherwise I can continue to
write my code for Delphi, and let it to somebody else to port that code
to e.g. FPC.
In the simplest case these units will have an unconditional interface
part, the target specific data type declarations and the implementation
part can be included conditionally from the appropriate locations. For
testing purposes fake units or code sections can contain the OS specific
procedure declarations, with empty bodies. This way I could verify that
my changes to the main stream code would not break the code for other
environments, due to the use of not yet ported constants or data types
etc.
This model has one disadvantage, in so far as complex procedures with
small embedded platform specific code could no more be checked, because
it often was impossible to determine the impact of changes to local
variables etc. in the conditionally excluded code. It also was and is
impossible to automatically verify that the conditional sections really
are implemented for every target!
In another implementation of a target independent library I defined
portable classes with standardized methods. These virtual methods were
almost abstract in the base class, so that they had to be overridden in
every derived class. In the initialization section of the unit the
appropriate class was created and assigned to the according variable,
based on the actual or desired target environment. Of course this
approach has the disadvantage of increasing runtime (how much?), due to
the virtual method calls. Nonetheless I think that in many cases the
difference from the traditional method will not be noticeable, due to
the (unknown, long?) runtime spent in the embedded OS calls.
The best compromise might be a mix of both methods. The interface can be
fully procedural, and objects with virtual methods are used only in the
implementation part, and only when this approach makes sense. Perhaps
somebody finds another way to achieve the same goal, with less
disadvantages?
I'm willing to demonstrate my ideas in a redesign and extension of
Abbrevia, so that we have a concreter base for further discussions. But
before starting with that work I would like to hear some encouraging <g>
opinions or suggestions.
DoDi
More information about the fpc-devel
mailing list