- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Apologies in advance for what seems to be a very basic question. I'm not a Fortran programmer, unfortunately, but I'm in a position of having to maintain some legacy FORTRAN77 code, and it is not compiling in Intel Visual Fortran Parallel XE 2013 (with VS2010) on Windows7.
The error I'm getting is
> error #6633: The type of the actual argument differs from the type of the dummy argument.
It occurs in several calls to subroutines that are defined within the project. This code has the statement
IMPLICIT REAL(8) (A-H,O-Z)
throughout, in both the calling function and the called subroutine. (It had been `REAL*8`, but I changed it.)
Doesn't that mean that the arguments, all of which have names that fall into the range (A-H,O-Z), will be two-byte reals? I don't know where they are being declared or otherwise converted to any other type. The only functions called within the subroutines are intrinsic math functions, such as cos, sin, atan2.
Below is an example (I left out an INCLUDE statement that included a file with the IMPLICIT REAL statement above as its first line):
C Transform from RS to RL call RS$RL(0,iobl,1,vrel,xlatgc,gam,az,vph,vth,vr, * xlatgd,gaml,azl,vphl,vthl,vrl)
which calls
SUBROUTINE RS$RL(ID,IOBL,IV,VREL,TH,GAM,AZ,VPH,VTH,VR, * THL,GAML,AZL,VPHL,VTHL,VRL) C* DECLARATIONS IMPLICIT REAL(8) (A-H,O-Z) C IMPLICIT REAL*8(A-H,O-Z) DEL = THL-TH IF(ID.EQ.0) THEN C* TRANSFORM FROM RS TO RL FRAME IF(IV.EQ.0) THEN VPH = VREL*COS(GAM)*SIN(AZ) VTH = VREL*COS(GAM)*COS(AZ) VR = VREL*SIN(GAM) ENDIF IF(IOBL.EQ.0) THEN VPHL = VPH VTHL = VTH VRL = VR ELSE VPHL = VPH VTHL = VTH*COS(DEL)-VR*SIN(DEL) VRL = VTH*SIN(DEL)+VR*COS(DEL) ENDIF GAML = ATAN2(VRL,SQRT(VPHL**2+VTHL**2)) AZL = ATAN2(VPHL,VTHL) ELSE C* TRANSFORM FROM RL FRAME TO RS FRAME IF(IV.EQ.0) THEN VPHL = VREL*COS(GAML)*SIN(AZL) VTHL = VREL*COS(GAML)*COS(AZL) VRL = VREL*SIN(GAML) ENDIF IF(IOBL.EQ.0) THEN VPH = VPHL VTH = VTHL VR = VRL ELSE VPH = VPHL VTH = VTHL*COS(DEL)+VRL*SIN(DEL) VR =-VTHL*SIN(DEL)+VRL*COS(DEL) ENDIF GAM = ATAN2(VR,SQRT(VPH**2+VTH**2)) AZ = ATAN2(VPH,VTH) ENDIF RETURN END
The error messages complain about the arguments, vrel, xlatgc, gam, az.
Any suggestions or clues are much appreciated.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Where you have the call statement, you will have to check the variable types of the arguments being passed, to assure that they match those of the subroutine being called. Unlike C/C++, Fortran will not promote/demote arguments being passed, as these are generally by reference, not value.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I see you also asked this at StackOverflow. In our implementation, REAL(8) and REAL*8 mean the same thing - an 8-byte (not 2-byte) real.
In general, any reliance on implicit typing is bad. What happens if you add explicit declarations of the variables in the caller?
It would really help if you could post a complete, small source that demonstrates the problem. My experience is that excerpts often omit critical information.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
We need to see the declarations made in the caller
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
None of the variables in the argument to the subroutine are explicitly declared anywhere - that's why I mention the use of
IMPLICIT REAL(8) (A-H,O-Z)
The calling function has the statement
INCLUDE 'common.f'
at the top, and the file common.f has the IMPLICIT statement above as its first line, followed by a bunch of explicit declarations, none of which include any of the variables in the argument to the subroutine. (The declarations are only for a set of variables that are used in calls to a third-party dynamically linked library.)
I can try to create a small dummy program to see if I can replicate the problem, but this particular project is kind of elaborate, so extracting just the minimum amount of code to reproduce it might be time-consuming. I'll give it a shot, though, since I recognized that these out-of-context snippets make it difficult to tell what's really happening.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here's another thought, which has occurred to me as I attempt to create a short version of my problem:
The variables in question are often set by use of lines like:
RAD = 180.D0/PI
That `180.D0` sets RAD with a double-precision value, doesn't it? I generally think of REAL*8 as being loosely the same as double-precision (I realize they aren't exactly synonymous), so could that be related to my problem?
In other words, if variable RAD is IMPLICITly of type real*8, is it wrong to initialize it as above?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, it's not wrong. But you should be able to show us a compilable source that demonstrates the problem. Please do so.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That error message normally dives some names for the variable in the call it does not like, post the log file for the compile or at least the exact errors for the code snipped you posted.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When you say the calling function has the INCLUDE statement - can you check that there isn't an END statement or similar in between the INCLUDE with the IMPLICIT and the CALL. I wonder whether the INCLUDE (and hence the IMPLICIT statement) is in a different scope. Fortran is not a file scoped language - which has confused some coming from different languages previously.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve Lionel (Intel) wrote:
No, it's not wrong. But you should be able to show us a compilable source that demonstrates the problem. Please do so.
I'm working on it! The problem is that this program is a couple thousand lines of the worst badly-written undocumented spaghetti code you've ever seen. It is the result of different analysts over the years cramming in whatever "fixes" they needed at a given moment, which they then left there for others to scratch their heads over. There are hard-coded values that override variables where you'd never expect it, there are blocks of code that can never be entered because someone short-circuited some branching logic, there are common blocks of variable that get declared inconsistently in different places - you get the idea.
My current goal to do discard all of this and to replace it with new code built from scratch, which I have done. My new code is not behaving entirely consistently with the old code, however, so now I want to build a debug version of the old code so that I can compare what they are doing and determine which one is correct. That is the only reason I'm even trying to compile this code, and I'll be happy if I never have to look at it again after I'm done.
Sorry for the rant, but I thought it might help to give some context. The point is only that it's not trivial to extract only the parts that are causing my errors. That requires working backward to find everything that led up to the point where these calls are made and to see how each of the input arguments got its values by then. I've got many pages of printouts spread around so that I can trace all the spaghetti from one place to another.
Here's where I've gotten: The inputs to these subroutine calls are not declared explicitly anywhere, so they must be real(8) because of those IMPLICIT statements. Their values, however, derive from other variables that were declared in the INCLUDE file as plain REAL.
The following compiles, however, so I don't think this is the source of my problem (?).
IMPLICIT REAL(8) (A-H,O-Z) REAL X X = 1.D0 Y = X*2D0 CALL MYSUBR(Y,Z) WRITE(*,'(f3.1)') Z SUBROUTINE MYSUBR(Y,Z) IMPLICIT REAL(8) (A-H,O-Z) Z = Y*3D0
(I know a normal person wouldn't write those "D0"s, but that's the kind of thing that's all throughout this code.)
I'll try to get a mini-program done that produces the error. Please stay tuned, and thanks for the help.
Bruce
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
John Campbell wrote:
I converted your code examples into a simple program and did not reproduce the error message.
This would imply to me there are some explicit declarations for some of the arguments where RS$RL is being called.
John
I've searched all the source files for any explicit declarations for those specific arguments, and there are none. What I'm tracing right now is how those arguments got their values, because they are derived from other variables that were declared as REAL. The only other explicit declarations for numeric types are for INTEGER, but I don't think any of these arguments derived from INTEGERs. I'm still checking.
IanH wrote:
When you say the calling function has the INCLUDE statement - can you check that there isn't an END statement or similar in between the INCLUDE with the IMPLICIT and the CALL. I wonder whether the INCLUDE (and hence the IMPLICIT statement) is in a different scope. Fortran is not a file scoped language - which has confused some coming from different languages previously.
No, no END statement until the very end of the calling subroutine.
I was curious about what would happen if I inserted the IMPLICIT statement directly into the calling subroutine, however. I tried that and got this:
error #6222: This IMPLICIT statement is not positioned correctly within the scoping unit.
which I don't understand, so that makes me immediately suspicious that I'm doing something wrong.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Bruce,
As mentioned in some of the above comments, if you can share your "common.f" include file itself or its details, someone may be able to help you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
FortranFan wrote:
Bruce,
As mentioned in some of the above comments, if you can share your "common.f" include file itself or its details, someone may be able to help you.
Okay. I've been hesitant to post full examples because it's pretty bloated, but here is the common.f file with only comment lines stripped out:
C DECLARE VARIABLES IMPLICIT REAL(8) (A-H,O-Z) C IMPLICIT REAL*8 (A-H,O-Z) INTEGER num_bin_mass, num_bin_dia, state_max, maxmat INTEGER driverversion PARAMETER ( num_bin_mass = 10 ) PARAMETER ( num_bin_dia = 10 ) C PARAMETER ( state_max = 3000. ) ! For COLA - reduced for v.6.8 to avoid link error PARAMETER ( state_max = 3000000. ) ! For COLA C The next four parameters are kernel version-dependent and should be C changed only when updating for a new kernel. PARAMETER ( maxmat = 150 ) PARAMETER ( maxoptions = 14 ) PARAMETER ( maxiret = 62 ) PARAMETER ( driverversion = 6080000 ) !!!! UPDATE FOR NEW KERNEL VERSIONS !!! REAL, ALLOCATABLE :: state_frag(:,:,:) REAL, ALLOCATABLE :: state_rcs(:,:,:,:) REAL tmass(3), inp_vel(3,2), cld_vel(3,3), size(3) REAL int_ang, velocity(2), spin(2) REAL bin_mass(num_bin_mass), bin_dia(num_bin_dia) REAL num_mass(num_bin_mass,3), num_dia(num_bin_dia,3) REAL vel_mass_col(num_bin_mass,3), vel_dia_col(num_bin_dia,3) REAL col_eng(3,3), col_lit_eng, exp_eng(3,3), exp_oth_eng c REAL, ALLOCATABLE :: state_frag(state_max,25,3) REAL t_init(3) REAL tem_mass(num_bin_mass,3), tem_dia(num_bin_dia,3) REAL mass_mass(num_bin_mass,3), mass_dia(num_bin_dia,3) REAL kk1(3), kk2(3), kpow(3) INTEGER iret(maxiret), options(maxoptions) INTEGER he_flag, state_num(3), k, j, i, dead, ii INTEGER lethal_flag, state_opt, seed_ic, seed_it INTEGER target, ballast, nmat(3), use_default(3) REAL csm_in(6), csm_out(5), number_sm c Next four variables reduced from 2-D to 1-D arrays for v.5.4 -ble REAL num_mass_sm(num_bin_mass), num_dia_sm(num_bin_dia) REAL mass_mass_sm(num_bin_mass), mass_dia_sm(num_bin_dia) REAL mater_fract(maxmat,3), mater_thick(maxmat,3) C---- msl_save_out: First dim increased to 12, v6.0 1/15/08 jbf REAL msl_save_out(12,3) REAL wave, sum_mass(2), sum_ke(2), mass(2) REAL state_thres(3) REAL he_mass, ca_mass REAL rp_mass REAL mass_phits(2,3), density(3), ktermm(4), spin2(2) REAL vel_dia_xfer(num_bin_dia,3), vel_mass_xfer(num_bin_mass,3) REAL diameter(3), bst_size_in(4), bst_mass_in(4) INTEGER at_bst, mater_id(maxmat,3), hit_bst INTEGER bst_in(3) INTEGER rv_num_mat_in, kv_num_mat_in, bst_num_mat_in(4) REAL rv_mater_fract_in(maxmat), rv_mater_thick_in(maxmat) REAL rv_mater_2_debris_in(maxmat,2) INTEGER rv_mater_id_in(maxmat) REAL kv_mater_fract_in(maxmat), kv_mater_thick_in(maxmat) REAL kv_mater_2_debris_in(maxmat,2) INTEGER kv_mater_id_in(maxmat) REAL bst_mater_fract_in(maxmat,4), bst_mater_thick_in(maxmat,4) REAL bst_mater_2_debris_in(maxmat,4) INTEGER bst_mater_id_in(maxmat,4) C ----- FROM KIDD V3.5 DrvMod2.for ----- COMMON /CONSTS/ GO,RAD,PI,ECC,RPO,REQ,XMU,EPS,GSL,WE,RE INTEGER*2 IY,IM,ID INTEGER IRAN, JRAN(2) INTEGER, ALLOCATABLE :: SEED (:) REAL XRAN (2) character*80 title character*60 text(16),filein,fileout,fpout,ftout,fbout,filename, *fleg,fheg,fone,filemc character*250 text2(6) C --- ccc update for V4.1 C character*60 forg,texto(8) character*60 forg,texto(10) CHARACTER*1 ENAME(3) CHARACTER*3 DNAME dimension jdate(3),gam0(3),az0(3),vel0(3),gamcl(3),azcl(3), * velcl(3),veltcl(3),velteci(3),irng(3),rmax(3),irmax(3), * bcemin1(3),bcemin2(3),bcemin3(3),delvm1(3),delvm2(3), * delvm3(3),iwlim(3), iengl1(3),iengl2(3),sumw(3), * i1(3),i2(3),i3(3),iv1(3),iv2(3),iv3(3), * fltmc(20,200,3),xval(200),rapog(3),irapog(3), * xmed(20),xmea(20),xmin(20),xmax(20),bcemax1(3), * bcemax2(3),bcemax3(3),ii1(3),ii2(3),ii3(3) C Parameters added for v.4.2.2 -ble INTEGER state_csm REAL deltav(3), xfer(5,3), factor C Parameters added for v.5.0.1 -ble REAL cb_in(6), pb_in(6), number_cb, number_pb REAL cbpb_mater_fract_in(maxmat), cbpb_mater_thick_in(maxmat) INTEGER cbpb_mater_id_in(maxmat), cbpb_num_mat_in REAL num_dia_cbpb(num_bin_dia), mass_dia_cbpb(num_bin_dia) REAL num_mass_cbpb(num_bin_mass), mass_mass_cbpb(num_bin_mass) REAL cbpb_density, cbpb_mass_phits(2), cb_out(9), pb_out(9) c REAL cb_save(18), pb_save(18) REAL cbpb_mater_fract(maxmat), cbpb_mater_thick(maxmat) INTEGER cbpb_num_mat, cbpb_mater_id(maxmat) INTEGER version, state_cbpb C *************** Parameters added for v.5.2 -ble ******************* C Inputs REAL pca_z INTEGER num_bolts_in(4), bolt_mat_in(4) INTEGER shell_mat_in(4), bst_joint_type(4) REAL bolt_dia_in(4), shell_thick_in(4) C Outputs INTEGER bst_num_sec_out, joint_ok(4) REAL bst_size(4), bst_mass(4) C *************** Parameters added for v.5.4 -ble ******************* C msl_save_in: First dim inc to 12 v6.0 1/15/08 jbf C cb_save_in, csm_save_in, pb_save_in: Dim inc to 19 v6.0 1/15/08 jbf C cb_save_out, csm_save_out, pb_save_out: Dim inc to 19 v6.0 1/15/08 jbf REAL msl_save_in(12,3), csm_save_in(19) REAL cb_save_in(19), pb_save_in(19) REAL mtt_save_in, mtt_save_out CHARACTER*255 path_name, target_name, cl_level_tgt REAL csm_save_out(19),cb_save_out(19), pb_save_out(19) C *************** Parameters added for v.6.0 jbf ******************* CHARACTER*255 dotkid_path_fname_in c KIDD_KERNEL input/output arguments INTEGER ran_num_gen_io(48) c KIDD_KERNEL output arguments INTEGER iret_warnings INTEGER iret_errors INTEGER iret_fatal C *************** Parameters added for v.6.5 ble ******************* INTEGER num_multi_waves C PARAMETER ( num_multi_waves = 3 ) PARAMETER ( num_multi_waves = 0 ) REAL wave_multi(num_multi_waves) INTEGER state_goal(3) C REAL state_rcs(state_max,4,num_multi_waves,3) C *************** Parameters added for v.6.8 ble ******************* CHARACTER*255 interceptor_name CHARACTER*255 cl_level_int
The majority of the variables in these declarations are arguments that get passed in a call to a third-party dynamic link library (this program is actually a driver for the computational kernel in that library). There is a single call to the kernel, which has around 200 arguments, all of which appear somewhere in the declarations above.
Our driver code does some additional computations, such as the subroutine I posted in the original post, but with only a few exceptions the variables used in those computations are not explicitly declared.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Do you understand that if you have IMPLICIT REAL(8) that this applies only to variables not explicitly declared? This source is full of explicit REAL declarations, which means REAL(4).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Among the difficulties with the implicit real is that I think the compiler will not see a variable typed that way as having the same type as an explicit REAL declaration, even if one attempts to reconcile them using /real-size: or some equivalent legacy option. So you will need to make your source code more standard or turn off the warning.
Neither IMPLICIT REAL(8) nor IMPLICIT REAL*8 is Fortran 77, as far as I know, even though most compilers had some such extension for compatibility with IBM legacy, and many people considered it a required extension without which they would refuse to use f77. REAL(8) doesn't have much advantage, as it's still not portable, even though it conforms to f90 under the condition that it matches the types supported by a given compiler.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve Lionel (Intel) wrote:
Do you understand that if you have IMPLICIT REAL(8) that this applies only to variables not explicitly declared? This source is full of explicit REAL declarations, which means REAL(4).
Yes, I do understand that. That's why I tried the little program in my previous response. I declared X explicitly as REAL but let Y and Z be implicitly declared as REAL(8), and then passed them both to the subroutine, which mimics at least some of what's going on in my real code. This didn't produce the compile error, however.
Nonetheless, I'm pretty sure the error originates from some inconsistency in declarations somewhere deep in the mess of code I'm dealing with. There are so many lines lines of uncommented code that it requires a lot of detective work to figure out where variables came from, however - especially when they're not explicitly declared and many of them are in common blocks. Variables just appear out of nowhere, and you have to search for where they were first defined.
I feel like I'm wasting your time, so if you want to leave me to it, I'll just continue my attempt to pare the code down to the minimum that will trigger the same error. I'm betting that in the process I'll uncover the source of the error, but if not, then I'll post whatever I came up with.
Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
None of the actual arguments to the procedure in question seem to be declared explictly in the include "common.f", so differences between an implicit REAL(8) for the dummy argument and default REAL in an explicit declaration for the actual argument can't explain the original error.
Something else is amiss.
Bruce, if you want this forum to help you, I am afraid you'll have to provide the details of the caller procedure.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
FortranFan wrote:
None of the actual arguments to the procedure in question seem to be declared explictly in the include "common.f", so differences between an implicit REAL(8) for the dummy argument and default REAL in an explicit declaration for the actual argument can't explain the original error.
Something else is amiss.
Bruce, if you want this forum to help you, I am afraid you'll have to provide the details of the caller procedure.
Yes, I agree with everything you said.
As I mentioned in my previous response, I think I'm just wasting your time until I can produce a small piece of code that produces the same error. The calling function in question is in a file with 2838 lines (including comments, but still ...), and you'll have to take my word for it that you do not want to see this - it's really horrible.
If I can't discover the source of the error in the process of producing this smaller piece of code, then I'll post it, and we can take it from there.
Thanks to everyone for the responses.
Bruce
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, we do want to see it. We don't care how horrible the code is, we want a compilable source we can examine. If you want to provide it privately, use "Send Author a Message" and attach a ZIP of the needed files there.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve Lionel (Intel) wrote:
Yes, we do want to see it. We don't care how horrible the code is, we want a compilable source we can examine. If you want to provide it privately, use "Send Author a Message" and attach a ZIP of the needed files there.
Done! Thanks.
Of course, this isn't really a compilable source. The last time I was able to compile this code was using Compaq Visual Fortran on WinXP. That's the whole problem - I can't compile it any more.
Bruce
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page