- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I guess Yes.
You must change all
CALL DSSPOS ( MCBLT,
to
CALL DSSPOS ( MCBLT(1),
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>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
![](/skins/images/7B0AB6865064EAE32B30EC9A4E94B48A/responsive_peak/images/icon_anonymous_message.png)
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page