Type mismatch problem FORTRAN 77

  • Context: Fortran 
  • Thread starter Thread starter Peptid
  • Start date Start date
  • Tags Tags
    Fortran Type
Click For Summary

Discussion Overview

The discussion revolves around a type mismatch error encountered while compiling a FORTRAN 77 code. Participants explore the cause of the error related to the function 'cmod' and its interaction with the function 'ERREV', focusing on type declarations and potential solutions.

Discussion Character

  • Technical explanation
  • Debate/contested

Main Points Raised

  • Batu reports a type mismatch error indicating a return type mismatch of function 'cmod' when compiling the FORTRAN code.
  • One participant suggests removing the "D" prefix from intrinsic functions and requests the complete error message for better context.
  • Another participant argues that the "D" prefixes may not be necessary but insists that the function 'CMOD' needs to be declared as REAL*8 in 'ERREV' to avoid the mismatch error.
  • A different participant acknowledges the potential irrelevance of the "D" prefix removal but suggests that the code appears outdated and could benefit from modernization, including clearer formatting and structure.
  • Batu confirms that adding the line REAL*8 CMOD resolved the error, expressing gratitude for the advice received.
  • Batu mentions the code is lengthy and not originally written by them, indicating a willingness to consider future improvements based on suggestions if licensing allows.

Areas of Agreement / Disagreement

Participants generally agree on the need to declare the type of 'CMOD' in 'ERREV' to resolve the error. However, there are differing opinions on the necessity of the "D" prefix and the overall structure of the code, with some advocating for modernization while others focus on immediate fixes.

Contextual Notes

Participants note that the code may have been written in an older style, potentially complicating its readability and maintainability. There are also references to the differences in handling types between FORTRAN 77 and later versions, which may influence the discussion.

Peptid
Messages
4
Reaction score
0
Hi all,

I am trying to run a long FORTRAN 77 code in my laptop. Document contains a makefile and it is instructed to use 'make pgi' command to compile. Beside many warnings, each time I enter that command, it returns me ' Return type mismatch of function 'cmod' at (1) (REAL(4)/REAL(8))
analsubs.f90:766.13'

The relevant part of the code is:
REAL*8 FUNCTION ERREV(NN,QR,QI,MS,MP,ARE,MRE)
REAL*8 QI(NN), QR(NN),MS,MP,ARE,MRE,E
E =CMOD(QR(1),QI(1))*MRE/(ARE+MRE)
DO 10 I=1,NN
E = E*MS+CMOD(QR(I),QI(I))
10 CONTINUE
ERREV = E*(ARE+MRE)-MP*MRE
END FUNCTION errev

and part for 'cmod' is:

REAL*8 FUNCTION CMOD(R,I)
REAL*8 R,I,AR,AI,DABS,DSQRT
AR = DABS(R)
AI = DABS(I)
IF (AR .GE. AI) GO TO 10
CMOD = AI*DSQRT(1.0D0+(AR/AI)**2)
RETURN
10 IF (AR .LE. AI) GO TO 20
CMOD = AR*DSQRT(1.0D0+(AI/AR)**2)
RETURN
20 CMOD = AR*DSQRT(2.0D0)
END FUNCTION cmod

I don't understand the reason of the error since I believe that both AR and AI in cmod are defined in type REAL*8. Is there anyone who has an idea about it?

Thanks in advance,
Batu
 
Technology news on Phys.org
Stop using "D" as a prefix in the intrinsic functions and tell me what happens.

Also, please post the entire error message...I am sure that "1" is strategically placed under some line to indicate exactly where fortran thinks the problem is.
 
I don't thinkg gsal's advaice is relevant. (the D prefixes might not be necessary, but that doesn't make them wrong!)

You need to add the line
REAL*8 CMOD
in function ERREV. Each function or subroutine of a Fortran program is compiled independet of everyting else. You didn't declare the type of CMOD in ERREV, so the compiler assumes it is REAL*4. Later, when all the functions are linked together to make the executable program, that turns out to be wrong and you get the error.
 
I admit, maybe the removal of "D" is not quite the best thing to do...I forgot that you are using Fortran77...I think in Fortran90 (and beyond), the "D" would be unnecessary since Fortran90 can choose the correct function for you automatically.

By the way, how long is you code? I don't know about you but, after a better look at the source, I wouldn't resist the urge to modernize it. You might be using Fortran77, but it looks like this code was written in Fortran66 at most...that spaghetti code with the GOTO's gives it away...it's confusing to figure out what's supposed to be done when. I would also stop using uppercase all over, it's just make the screen so crowded.

You can start by explicitly writing it out and THEN optimize a bit. For example, first shot:
Code:
real*8 function cmod(r,i)
    real*8 r,i,ar,ai,dabs,dsqrt
    
    ar = dabs(r)
    ai = dabs(i)
    
    if (ar .lt. ai) then 
        cmod = ai*dsqrt(1.0d0+(ar/ai)**2)
        return
    end if
    
    if (ar .gt. ai) then 
        cmod = ar*dsqrt(1.0d0+(ai/ar)**2)
        return
    end if

    if (ar .eq. ai) then 
        cmod = ar*dsqrt(2.0d0)
        return
    end if    
    
end function cmod

Then again, the "if (ar .eq. ai) then" is not quite necessary since both of the previous equations would turn into this one for the case when ar.eq.ai; so, we could turn one of the other two into ".le." or ".ge."

Code:
real*8 function cmod(r,i)
    real*8 r,i,ar,ai,dabs,dsqrt
    
    ar = dabs(r)
    ai = dabs(i)
    
    if (ar .le. ai) then 
        cmod = ai*dsqrt(1.0d0+(ar/ai)**2)
        return
    end if
    
    if (ar .gt. ai) then 
        cmod = ar*dsqrt(1.0d0+(ai/ar)**2)
        return
    end if
    
end function cmod

Now, the two "IF" statements lend themselves to be put into a single "IF-THEN-ELSE" block

Code:
real*8 function cmod(r,i)
    real*8 r,i,ar,ai,dabs,dsqrt    
    
    ar = dabs(r)
    ai = dabs(i)
    
    if (ar .le. ai) then 
        cmod = ai*dsqrt(1.0d0+(ar/ai)**2)
    else
        cmod = ar*dsqrt(1.0d0+(ai/ar)**2)
    end if
    
    return
end function cmod

...now, that's a nice looking function :-)

my 2 cents
 
Adding the line REAL*8 CMOD solved the problem and this time I didn't get any error message. I thank you very much for the advice AlephZero.

gsal, the file is about 1500 lines long and worse is that I didn't write the code. This is a part of my project and I am trying to make it run first. Fortran 77, says the manual:) I do appreciate your help and will most probably change the parts as the way you have suggested if there will be no license issues.
 

Similar threads

  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 9 ·
Replies
9
Views
5K
  • · Replies 22 ·
Replies
22
Views
5K
Replies
6
Views
4K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 54 ·
2
Replies
54
Views
5K
  • · Replies 3 ·
Replies
3
Views
16K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 1 ·
Replies
1
Views
3K