fpt and WinFPT Reference Manual - Command-line Commands

| SimCon Home | Ref Manual Home |

MOVE DATA IN COMMON TO BLOCK DATA

Syntax:

[DO NOT] MOVE DATA IN COMMON [TO BLOCK DATA]

Function:

This command addresses an issue in software migration, in particular from VMS. VMS allows multiple initialisations of objects in COMMON blocks outside BLOCK DATA

fpt identifies all situations where objects in COMMON blocks are initialised by data outside BLOCK DATA sub-programs. If the COMMON block is already referenced in a BLOCK DATA sub-program the data initialisation is moved to that sub-program. If no BLOCK DATA sub-program already exists for the COMMON block a new BLOCK DATA sub-prgram is created. The new sub-program may be written to a new file, named <common_name>_bda.f90 (where the extension .f90 may be changed to the current primary output file name extension), or appended to the file of each program which requires the initialisation. The behaviour is controlled by the command ATTACH NEW BLOCK DATA TO THEIR PROGRAMS. The new BLOCK DATA sub-program is named <common_name>_bda.

Declaration of the Variables Which Receive Data

When fpt creates a new BLOCK DATA sub-program the variables which receive data must be declared. Type declarations are inserted. The COMMON declaration is made by declaring a backbone array for the COMMON block of type INTEGER(1) and writing an EQUIVALENCE statement to position the variables at the correct COMMON block addresses. This avoids the need to declare every variable in the COMMON block in the new BLOCK DATA.

The declaration of variables may require declaration of Fortran parameters, derived types and structures. These declarations are inserted before the declaration statements of the variables.

Moving Data in COMMON

There are three cases where data initialisations must be moved.

  1. Simple data statements, e.g. DATA n /42/
  2. Data embedded in declarations, e.g. INTEGER(4) :: n = 42
  3. Default initialisation of structures or derived types.

Moving simple DATA statements

Simple DATA statements are commented-out in the original code and transcribed to the new or existing BLOCK DATA sub-program. For example, the program:

PROGRAM t_simple_data INTEGER(4),PARAMETER :: life_universe_etc = 42 COMMON /c/ i,j,n DATA n /life_universe_etc/ CALL s END PROGRAM t_simple_data

is re-written:

PROGRAM t_simple_data ! INTEGER(4),PARAMETER :: life_universe_etc = 42 COMMON /c/i,j,n ! FPT DATA n/life_universe_etc/ !------------^----------------------------------------------------------------- !!! FPT - 4271 DATA in COMMON moved to BLOCK DATA !------------------------------------------------------------------------------ ! CALL s ! END PROGRAM t_simple_data

and the new BLOCK DATA sub-program is written:

BLOCK DATA c_bda !-----------------------^------------------------------------------------------ !!! FPT - 4293 New BLOCK DATA sub-program created for DATA in COMMON !------------------------------------------------------------------------------ ! IMPLICIT NONE INTEGER*4,PARAMETER :: life_universe_etc = 42 ! INTEGER*1 c_backbone(0:11) COMMON /c/c_backbone ! INTEGER*4 :: n EQUIVALENCE (n,c_backbone(8)) ! DATA n/life_universe_etc/ ! END BLOCK DATA c_bda

Moving Data Written in Declarations

If the same COMMON block is initialised by data in two or more sub-programs recent versions of most compilers will compile the code but the code will not link. The COMMON block is reported as a duplicate definition (e.g. gfortran Ubuntu 10.3.0, ifort 2021.4.0 20210910). fpt converts the two files:

File: t_data_in_declaration.f90 PROGRAM t_data_in_declaration INTEGER(4) :: three(3) = (/ 1,2,3 /) INTEGER(4) :: four(4) COMMON /c_data_in_declaration/ three,four CALL s_data_in_declaration END PROGRAM t_data_in_declaration File s_data_in_declaration.f90 SUBROUTINE s_data_in_declaration INTEGER(4) :: three(3) INTEGER(4) :: four(4) = (/ 1,2,3,4 /) COMMON /c_data_in_declaration/ three,four WRITE(*,'(3I4,2X,4I4)') three,four END SUBROUTINE s_data_in_declaration

to the three files:

File: t_data_in_declaration.f90 PROGRAM t_data_in_declaration ! ! FPT INTEGER(4)::three(3)=(/1,2,3/) !--------------^--------------------------------------------------------------- !!! FPT - 4269 Embedded DATA in COMMON moved to BLOCK DATA !------------------------------------------------------------------------------ INTEGER(4)::three(3) INTEGER(4)::four(4) ! COMMON /c_data_in_declaration/three,four ! CALL s_data_in_declaration ! END PROGRAM t_data_in_declaration File s_data_in_declaration.f90 SUBROUTINE s_data_in_declaration ! INTEGER(4)::three(3) ! FPT INTEGER(4)::four(4)=(/1,2,3,4/) !--------------^--------------------------------------------------------------- !!! FPT - 4269 Embedded DATA in COMMON moved to BLOCK DATA !------------------------------------------------------------------------------ INTEGER(4)::four(4) ! COMMON /c_data_in_declaration/three,four ! WRITE (*,'(3I4,2X,4I4)')three,four ! END SUBROUTINE s_data_in_declaration File c_data_in_declaration_bda.f90 BLOCK DATA c_data_in_declaration_bda !-------------------------------------------^---------------------------------- !!! FPT - 4293 New BLOCK DATA sub-program created for DATA in COMMON !------------------------------------------------------------------------------ ! IMPLICIT NONE ! INTEGER*1 c_data_in_declaration_backbone(0:27) COMMON /c_data_in_declaration/c_data_in_declaration_backbone ! INTEGER*4::three(3) EQUIVALENCE (three,c_data_in_declaration_backbone(0)) ! INTEGER*4::four(4) EQUIVALENCE (four,c_data_in_declaration_backbone(12)) ! DATA three/1,2,3/ DATA four/1,2,3,4/ ! END BLOCK DATA c_data_in_declaration_bda

The program then compiles and links successfully.

Note a detail in the handling of the DATA statements for the arrays three and four. In the original initialisations in declaration the arrays are written, for example, (/ 1,2,3 /). In the DATA statements the (/ /) or [ ] must be removed. The are rejected on compilation.

Default Initialisation of Derived Types and Structures

When a derived type or a structure is declared, the components of the type or records of the structure may be initialised. The initialisation is applied to all variables of the derived type or structure. However, these variables may not be placed in COMMON blocks. This restriction appears to have been made because it was not possible to implement the language construct with the linkers available under Unix, Linux and Windows. Under VMS default initialisation of objects in COMMON has always been legal and is (or at least was) widely used.

There are several issues in converting programs with default initialisation of variables in COMMON. The issues are described for derived types. The reatment of structures is closely similar.

There may be many variables of the derived type, not all of which may be in COMMON blocks. The default initialisation must be applied to all of the variables which are not in COMMON. Therefore two different versions of the derived type must be declared, one with default initialisation and one without.

The variables in COMMON are then declared to be of the derived type without default initialisation and are initialised in BLOCK DATA.

The variables in COMMON are then of a different derived type from the local variables. Assignment between the types is no longer legal. The simplest way to overcome this is to use TRANSFER constructs and these are inserted by fpt.

The following example shows the handling of a Fortran STRUCTURE. This is the case most often encountered in migrating VMS code. The STRUCTURE construct is supported by ifort. The original program is:

PROGRAM t_default_init_structure STRUCTURE /default_init/ INTEGER(4) :: i = 0 END STRUCTURE RECORD /default_init/ i_local RECORD /default_init/ i_common COMMON /c_default_init_struct/ i_common i_local.i = 42 i_common = i_local WRITE(*,'("i_common: ",I4)')i_common END PROGRAM t_default_init_structure

fpt rewrites this code to:

PROGRAM t_default_init_structure ! STRUCTURE /default_init/ INTEGER(4)::i=0 END STRUCTURE ! STRUCTURE /default_init_common/ !--------------------------------------^--------------------------------------- !!! FPT - 4437 Declaration inserted to remove DATA initialisation from COMMON !------------------------------------------------------------------------------ INTEGER(4)::i END STRUCTURE ! RECORD /default_init/i_local RECORD /default_init_common/i_common !----------------------------------^------------------------------------------- !!! FPT - 4295 Declaration modified moving DATA initialisation to BLOCK DATA !------------------------------------------------------------------------------ ! COMMON /c_default_init_struct/i_common ! i_local.i=42 i_common=TRANSFER(i_local,i_common) !------------------------^----------------------------------------------------- !!! FPT - 4281 TRANSFER inserted to copy RECORD or Derived TYPE !------------------------------------------------------------------------------ ! WRITE (*,'("i_common: ",I4)')i_common ! END PROGRAM t_default_init_structure

The BLOCK DATA file created is:

BLOCK DATA c_default_init_struct_bda !-------------------------------------------^---------------------------------- !!! FPT - 4293 New BLOCK DATA sub-program created for DATA in COMMON !------------------------------------------------------------------------------ ! IMPLICIT NONE ! STRUCTURE /default_init_common/ !--------------------------------------^--------------------------------------- !!! FPT - 4437 Declaration inserted to remove DATA initialisation from COMMON !------------------------------------------------------------------------------ INTEGER(4)::i END STRUCTURE ! INTEGER*1 c_default_init_struct_backbone(0:3) COMMON /c_default_init_struct/c_default_init_struct_backbone ! RECORD /default_init_common/i_common EQUIVALENCE (i_common,c_default_init_struct_backbone(0)) ! DATA i_common.i/0/ !-------------------------^---------------------------------------------------- !!! FPT - 4199 DATA specification moved from STRUCTURE declaration !------------------------------------------------------------------------------ ! END BLOCK DATA c_default_init_struct_bda

Where to Use this Command

Operating system command line Yes
Configuration file, config.fsp Yes
Specification (fsp) files, *.fsp Yes
Interactively, to FPT> prompt Yes
Interactive command files Yes
Embedded in the Fortran code Yes

Default

No change is made by default.

Copyright ©1995 to 2024 Software Validation Ltd. All rights reserved.