Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

error#6634: the shape matching rules of actual arguments and dummy arguments have been violated.

Bowman__Eric
Novice
5,559 Views

I am trying to compile the NASTRAN code which was made open source by NASA a few years ago. 

I'm getting a lot of the following error: 


error #6634: The shape matching rules of actual arguments and dummy arguments have been violated.   [MCBLT] 

Although not always for the variable "MCBLT" that is just one case. 

Here is the code that is causing the error: 
   

      CALL DSSPOS ( MCBLT, LTPOS(5), LTPOS(6), LTPOS(7) )

 

MCBLT is defines in a common block here: 
 

      COMMON / OPINV  / MCBLT(7)  ,MCBSMA(7)


And here is the DSSPOS subroutine: 

      SUBROUTINE DSSPOS( FILE, KCBLK, KCLR, KCBP )
      C
      C DSSPOS REPOSITIONS THE "FILE" TO BLOCK "KCBLK" WITH THE CURRENT
      C LOGICAL RECORD POINTER SET TO "KCLR" AND THE CURRENT BUFFER
      C POINTER SET TO "KCBP"
      C
      INCLUDE 'DSIOF.COM'
      INCLUDE 'XNSTRN.COM'
      INTEGER    FILE
      NAME  = FILE
      CALL DSGEFL
      ICBLK  = FCB( 4, IFILEX )
      IF ( ICBLK .EQ. KCBLK ) GO TO 10
      NBLOCK = KCBLK
      CALL DBMMGR( 6 )
10    CONTINUE
      INDCLR = KCLR + INDBAS - 1
      INDCBP = KCBP + INDBAS - 1
      CALL DSSDCB
      RETURN
      END


So, MCBLT is an array, is there some implicit rule in GNU fortran 77 that if you pass an array into a subroutine for a scalar, then it simply grabs the first element or something like that? I know in C++ a pointer to an array is simply a pointer to its first element. 

 

Eric

0 Kudos
1 Solution
Steve_Lionel
Honored Contributor III
5,559 Views

There is no "implicit rule"; rather, many compilers don't have the ability to check for this violation of the Fortran standard. Intel Fortran does when you use the "generated interface checking" feature, which is on by default in new Visual Studio projects.

The NASTRAN code is simply wrong. That it "works" is an accident. I discussed this in https://software.intel.com/en-us/blogs/2009/03/31/doctor-fortran-in-ive-come-here-for-an-argument

The correct solution would be to pass MCBLT(1), etc. A less desirable solution is to turn off generated interface checking Fortran > Diagnostics > Check Routine Interfaces > No.

View solution in original post

0 Kudos
6 Replies
GVautier
New Contributor II
5,559 Views

I guess Yes.

You must change all

CALL DSSPOS ( MCBLT,

to

CALL DSSPOS ( MCBLT(1),

0 Kudos
Steve_Lionel
Honored Contributor III
5,560 Views

There is no "implicit rule"; rather, many compilers don't have the ability to check for this violation of the Fortran standard. Intel Fortran does when you use the "generated interface checking" feature, which is on by default in new Visual Studio projects.

The NASTRAN code is simply wrong. That it "works" is an accident. I discussed this in https://software.intel.com/en-us/blogs/2009/03/31/doctor-fortran-in-ive-come-here-for-an-argument

The correct solution would be to pass MCBLT(1), etc. A less desirable solution is to turn off generated interface checking Fortran > Diagnostics > Check Routine Interfaces > No.

0 Kudos
jimdempseyatthecove
Honored Contributor III
5,559 Views

If you happened to have placed SUBROUTINE DSSPOS into a module (or as a CONTAINS procedure)...
.OR. have compile time diagnostic warn:interfaces
Then in either case, you are in violation of the argument rules.

In the older versions of Fortran, there were no means to enforce interfaces.

Note, if you have DSSPOS located outside of a module or not a CONTAINED procedure .AND. do not have warn:interfaces enabled...
then the CALL would not have been flagged as in error.

Jim Dempsey

0 Kudos
Bowman__Eric
Novice
5,559 Views

Thank you for all the prompt answers. 

I turned off that flag just to see what would happen and that accounts for most of my compile errors.

I'll probably leave that flag off for now, get everything compiling so I can at least use the software and then flip the flag back on and fix the code. 

Eric
 

0 Kudos
LRaim
New Contributor I
5,559 Views

Leave things exactly as they are. In Fortran 77 as today what is important is the address of the variable which is the same as for
MCBLT or MCBLT(1). In C++ with the definition int MCBLT[6] you can call the subroutine as DSSPOS(MCBLT, ...   or DSSPOS(&MCBLT[0], 
i.e. the address of the entity is the same as the address of its 1st element. 

0 Kudos
jimdempseyatthecove
Honored Contributor III
5,559 Views

>>Leave things exactly as they are

Luigi has good advise. For your first version of adapting this program to run on your system using current compiler, linker, O/S, assume a rule from the Hippocratic Oath: Do no harm

As this applies to your programming: Do the least you can do in order to get the program to run and produce results within a margin of accumulated round off errors. Luigi's recommendation of modifying the argument at the place of call to MCBLT(1) would be the best choice. His C++ suggestion is likely not applicable seeing that C++ always had argument checking (function signatures) and would never have had the incorrect argument at function call.

For future reference: Be very careful when (if) you convert COMMONs to modules. These old programs ran on systems with limited memory, and quite often the named COMMONs would be mapped differently. If you are a C/C++ programmer, think of a named COMMON as a structure of bytes and the variables/arrays listed as an alternate structure that is unioned with the structure of bytes. Note, each procedure using the same named COMMON defines their own alternate structure that is unioned with the structure of bytes. The size of the structure of bytes will assume the size of the largest such union (same as with C/C++).

Jim Dempsey

0 Kudos
Reply