Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner
48 Views

Cannot disable Fortran error message 7615

I have a legacy application that needs to be integrated into a larger application. 

We have updated our development lab to Visual Studio 2017 and IFORT18, and are running into a problem.

Code that has compiled successfully for 4 decades has started throwing an error.  I cannot change this code module as it has been independently Verified and Validated, so inclusion in other code is fine.  Changing it is not. As the code is proprietary, I cannot show it here, but I was able to duplicate the problem in a small example (yes I know it's bad FORTRAN form ... It was valid at the time, and has passed IV&V)

I need to know what flag to set in visual studio to allow this code to compile under VS2017 and IFORT18.  It worked correctly on VS2010 and IFORT16.

----------------------   code and errors below -----------------------

C EQUIVELENCE BLOCK TEST

subroutine bar

COMMON / FOO / X1, Y1, Z1, X2

DIMENSION TEST(30)

EQUIVALENCE ( X1,TEST( 1) ), (Y1, TEST (3)),

2 (Z1, TEST (5)), (X2, TEST( 6))

END

Source1.for(10): error #7615: Multiple objects from the same EQUIVALENCE set may not appear in a COMMON block. [TEST]

Source1.for(11): error #7615: Multiple objects from the same EQUIVALENCE set may not appear in a COMMON block. [TEST]

Source1.for(11): error #7615: Multiple objects from the same EQUIVALENCE set may not appear in a COMMON block. [TEST]

 

 

 

0 Kudos
8 Replies
Highlighted
Valued Contributor III
48 Views

Look at https://software.intel.com/en-us/forums/intel-fortran-compiler-for-linux-and-mac-os-x/topic/747351

Your code is not valid fortran BTW so it is reasonable for the compiler to reject it.

0 Kudos
Highlighted
Black Belt
48 Views

I can only comment on the code shown, and IFort 16, as well as older compilers, reject it:

Intel(R) Visual Fortran Compiler for applications running on IA-32, Version 16.0.4.246 Build 20160811
Copyright (C) 1985-2016 Intel Corporation.  All rights reserved.

HENNING.F(2): error #6502: COMMON cannot be extended beyond the beginning of a block.   [Y1]
      COMMON / FOO / X1, Y1, Z1, X2
-------------------------^

CVF 6.6:

Compaq Visual Fortran Optimizing Compiler Version 6.6 (Update C)
Copyright 2003 Compaq Computer Corp. All rights reserved.

HENNING.F
HENNING.F(2) : Error: COMMON cannot be extended beyond the beginning of a block.   [Y1]
      COMMON / FOO / X1, Y1, Z1, X2
-------------------------^

The following sentence summarizes what the Fortran standard says about such code:

The same storage unit cannot occur more than once in a storage sequence, and consecutive storage units cannot be specified in a way that would make them nonconsecutive.

To see the problems that such code can create, suppose that in the subroutine you assign a value to TEST(2) or TEST(4). How should that affect the members of the common block?

Perhaps you can create a different example or explain in words what the equivalences are needed for. The example code that you gave contains no executable statements, so we have no idea as to what " It worked correctly" means.
0 Kudos
Highlighted
New Contributor II
48 Views

I would believe the following adaptation could be legacy code (pre F77), but the use of  ( X2, TEST( 6) ) would cause lots of problems. If it was used it would imply that Z1 was REAL. This would cause alignment issues with most post 70's compilers.

The likely reason for adopting this approach is a poor one, although it signals problems elsewhere in the "legacy" code.
You would also have to look at other uses of COMMON / FOO / as there would be mixing of variable types.

! EQUIVELENCE BLOCK TEST

      subroutine bar

      COMMON / FOO / X1, Y1, Z1, X2, bb(11)
      double precision X1,Y1,Z1,X2, bb
      integer          TEST(30)
      EQUIVALENCE ( X1, TEST(1) ), (Y1, TEST(3) ),  
     1            ( Z1, TEST(5) ), (X2, TEST(7) )       
!   ( X2, TEST( 6) ) would cause lots of problems

      END 

I needed a code type FORTRAN when posting this example

Actually, The use of multiple equivalence is unnecessary. The more likely original code would have been :

! EQUIVELENCE BLOCK TEST

      subroutine bar

      COMMON / FOO / TEST
      integer        TEST(30)
      double precision X1,Y1,Z1,X2
      EQUIVALENCE ( X1, TEST(1) ), (Y1, TEST(3) ),   
     1            ( Z1, TEST(5) ), (X2, TEST(7) )       

      END 

 

0 Kudos
Highlighted
New Contributor I
48 Views

You can insert only the first equivalence:
EQUIVALENCE ( X1,TEST( 1) )
​and use e.g. the address of TEST(5) for Z1.
Regards

 

 

0 Kudos
Highlighted
Black Belt
48 Views

There is a serious problem with equivalencing variables of different types, such as the equivalencing of integer variables to real/double variables as in #4. According to the Fortran standard (e.g., 16.5.6(1) of F2003)

When a variable of a given type becomes defined, all associated variables of different type become undefined.

Thus, assigning a value to X1 may cause TEST(1) and TEST(2) to become undefined. Assigning a value to TEST(2) or reading a value into TEST(2) may cause X1 to become undefined. Worse, such a bug can go undetected for a long time because compilers rarely emit extra code to make this un-definition happen.

 

0 Kudos
Highlighted
New Contributor II
48 Views

The second example in #4 was typically used in FTN legacy code when the compiler did static allocation of local variables.
This was when memory was limited, so local variables were equivalenced to a common block that was shared for temporary arrays. That they become undefined when no longer required is not a serious issue. This happens to all local variables in most modern compilers.

Although I did suggest this approach was a poor one, I was trying to give some context to why these equivalence statements would have been used 40 years ago. I have code dating back to that time, still in use and giving reliable results, that includes examples of EQUIVALENCE, which were probably for this purpose.

0 Kudos
Highlighted
New Contributor I
48 Views

In a piece of code which must reach a given result the difference should not related to modern or legacy but to efficient or inefficient.
This is a very recent example of use of EQUIVALENCE with COMMON structures.
!
      INTEGER (KIND=4), DIMENSION(:), POINTER :: NDSECT,KBSECT,ITSLUG
      REAL (KIND=8), DIMENSION(:,:), POINTER :: SL_PARM
      COMMON/CDY54_SLUG/NTDS,IA_SLUG,SL_PARM,
     &                  NDSECT,KBSECT,ITSLUG,  IL_SLUG
      INTEGER*4 AW_SLUG(100)
      EQUIVALENCE (NTDS,AW_SLUG(1))
      INTEGER*4  NW_SLUG/50/   ! warning, R*8 length
!
Best regards

0 Kudos
Highlighted
Black Belt
48 Views

John Campbell wrote:
The second example in #4 was typically used in FTN legacy code when the compiler did static allocation of local variables.

This was when memory was limited, so local variables were equivalenced to a common block that was shared for temporary arrays. That they become undefined when no longer required is not a serious issue. This happens to all local variables in most modern compilers.

Local variables become undefined only when a RETURN or END SUBROUTINE/FUNCTION is encountered. The effect of equivalence in causing undefinition, on the other hand, is immediate. In the following example, X is undefined when the PRINT is executed; in fact, it became undefined when a value was assigned to I.

program xeq
implicit none
integer i
real x
equivalence (i,x)
!
i=2
print *,x
end 

It should be noted that i and x need not be in memory at all. The integer variable I may be in a CPU register and the real variable X may be in a FPU register.

Normally, such equivalences do not cause problems. If, however, a user suspects undefined variable usage elsewhere in a program and compiles with checks for undefined variables, the presence of dissimilar type variables in EQUIVALENCE will cause a premature abort or the issuance of unwanted error messages when the program being checked is run.

0 Kudos