Here are some rules to keep FORTRAN Sources portable to other systems (APOLLO/UNIX, IBM/MVS/VM/AIX, etc. ). They help to keep the conversion efforts at a minimum. Many constructs allowed by VAX-FORTRAN are not accepted by others. 1. Bad (not accepted by non-VAX compilers) ===== PARAMETER I = 1 PARAMETER C = 'a' Good ====== INTEGER I PARAMETER ( I=1 ) CHARACTER*1 C PARAMETER ( C = 'a' ) 2. Bad (not accepted by non-VAX compilers) Good ===== ====== TYPE *, ... PRINT *, ... 3. Bad ===== INTEGER*4 FUNCTION xxxx() Good ====== INTEGER FUNCTION xxxx() 4. Bad Good ===== ====== BYTE CHARACTER*1 In addition, do not use strange data types like INTEGER*2 or LOGICAL*2 Use simply INTEGER and LOGICAL, which implies I*4 and L*4 by default on all machines I know of. 5. VAX-only ========== Variable Field widths: n = len(ccc) WRITE(6,'(A<n>)') ccc Portable (e.g.): ========== n = len(ccc) WRITE( cFmt,'(A,I3.3,A)' ) '(A',n,')' WRITE( 6, cFmt ) ccc or, simpler: n = len(ccc) WRITE(6,'(A)') ccc(1:nn) 6. Do not use logical operations (.AND., .OR., ... ) on INTEGER data. Do not use arithmetic operations (including assignments) on LOGICAL data. Do not use integer functions (e.g.IAND) on logical variables. Avoid the type-specific functions BITEST and BJTEST, use BTEST instead. Declare BTEST logical and assign its result to a logical variable. Do not use JIAND, JISHFT, et al., they are not available on all computers. The generic IAND is sufficient. 7. My APOLLO colleagues and I have detected subroutines without IMPLICIT NONE (especially in the CMD_xxx area). Shame on you !! 8. Stuff like: OPTIONS /EXTEND is *VAX-only*. It may be handled by FoFo's "conditional code generation" but it means that somewhere else in the program some non-standard FORTRAN is coded (in this case overlong lines). As a consequence this nonstandard code has to be #if'd too and the original advantage of saving typing effort is lost. So please avoid such constructs, the short-term gain is minimal compared to the additional porting effort. 9. None of the non-VAX compilers accepts (numeric) FORMAT SPEC.S without a field width: Bad: WRITE(6,'(I)') ii Good: WRITE(6,'(I12)') ii === ==== 10. Bad: ii = 4hPARA Better: CHARACTER*4 cc ==== ======= EQUIVALENCE(ii,cc) cc = 'PARA' 11. Bad: integer x /0/ Good: integer x === ===== data x /0/ 12. Variables in common-blocks need to be initialized by block data routines, not by simple data statements: Bad: data y /1.2/ Good: block data bd$tbc === common /tbc/ y ===== data y /1.2/ common /tbc/ y end ALL of the non-VAX compilers or linkers complain about the construct in the left hand column. 13. There are some problems with CHARACTER*(*) parameters ("inherited length operands") used in concatenations passed to other subroutines: SUBROUTINE xxx( cc ) CHARACTER*(*) cc CALL sub( '... ' // cc ) PRINT *,'... ' // cc Since the length of "cc" is not known at compile time the correct handling of such statements would require dynamic storage, a quite unusual and non-standard feature in FORTRAN. The different machines handle this problem in different ways (of course). - VAX: Compiler accepts, correct execution. Uses stack to hold the temporary concatenation. - IBM/MVS: Compiler accepts the PRINT, non-fatal error for the CALL, correct execution at run time. (a compiler-generated fixed-length intermediate storage is used. Its length is controlled by the CHARLEN() compiler option) - IBM/RS6000: Compiler complains with a non-fatal error. Correct execution at run time. Same technique as /MVS. - DECstation: Compiler does not accept nothing at all. (The -vms option does not help either). Suggestion: avoid such concatenations or use an explicitly coded concatenation to an auxiliary variable with "reasonable" length: CHARACTER*256 cTemp cTemp = '... ' // cc CALL sub( cTemp ) PRINT *, cTemp 14. The current version of FoFo does not handle overlong lines correctly, so please avoid them. Especially pay attention on lines starting with tabs: Tabs are considered one character by the VAX-compiler, so they may be followed by 71 characters without problems. As soon as FoFo has converted those tabs to eight blanks, however, there is trouble. 15. Do not use the intrinsic functions SIND, COSD, TAND and their inverse. They are not available on every computer. 16. Do not assign character data to integer arrays in DATA statements. That's invalid, although some compilers accept it. BAD: INTEGER ii Better: ==== ======= DATA ii / 'ABCD' / DATA ii / 4HABCD / 17. Do not use obscure random number generators that are not available on other computers. Use one of the CERNLIB instead. In addition, before coding utilities by yourself, look if you can find something in the CERN libraries. They are available on all computers we work on. This helps to reduce porting and coding effort and the executable's size. 18. When OPENing and CLOSing ordinary textfiles use PAOPEN and PACLOS. I/O statements are usually machine-dependent and may cause trouble. 19. To reduce porting effort to IBM/MVS and IBM/VM you should restrict external names (COMMONs and SUBROUTINES/ENTRYs) to 7 characters. Filenames should be not longer than 8 characters between periods to allow FTP without trouble to IBM/MVS and /VM. Please note that special characters in external and file names cause trouble on all computers I know of: $ and probably @ on UNIX, $, @ and # on VMS, _ on MVS, so avoid them.
fopi
Tue May 28 15:33:35 CST 1996