0

I have written two .f90 text files prog1.f90:

    PROGRAM prog1

        READ (5,*) A,B,C

        PRINT*, "A = ",A
        PRINT*, "B = ",B
        PRINT*, "C = ",C

    CALL test(A,B,C)


    END PROGRAM prog1

and aux.f90

    SUBROUTINE test(E,F,G)

        real(kind=8) :: E,F,G

        PRINT*,"E = ",E
        PRINT*,"F = ",F
        PRINT*,"G = ",G

    END SUBROUTINE test

Which are compiled using the Makefile:

    FC = gfortran
    FCFLAGS = -g -fbounds-check
    FCFLAGS = -O2
    FCFLAGS += -I/usr/include

    PROGRAMS = prog1 

    all: $(PROGRAMS)

    prog1: aux.o

    %: %.o
        $(FC) $(FCFLAGS) -o $@ $^ $(LDFLAGS)

    %.o: %.f90
        $(FC) $(FCFLAGS) -c $<

    %.o: %.F90
        $(FC) $(FCFLAGS) -c $<

    .PHONY: clean veryclean

    clean:
        rm -f *.o *.mod *.MOD

    veryclean: clean
        rm -f *~ $(PROGRAMS)

I use this makefile to compile prog1 and then run prog1 with the input file input.inp:

    0.0033943878 0.0018085515 0.0011798956

I expect the output of this code to be

    A = 0.339439E-02     
    B = 0.180855E-02     
    C = 0.117990E-02
    E = 0.339439E-02     
    F = 0.180855E-02     
    G = 0.117990E-02

However it is:

    A = 0.339439E-02     
    B = 0.180855E-02     
    C = 0.117990E-02
    E = 0.100765847236215E-21
    F = 0.750936901926887E-24
    G = 0.261410786221168-313

The number are much much smaller in the subroutine and seem to have no logical connection to the original A,B and C and are returned from the subroutine as such.

I take it my error is to do with the type I am storing these numbers as, i.e. they are not read in as real(kind=8) but are being converted into this type causing the error but I am not sure what the type should be in the subroutine or if this is even the cause. I may just be missing something obvious.

Any help would be appreciated and please tell me if I need to clarify anything I have written.

Thank you for your time.

James

James
  • 105
  • 3
  • 17
  • Please find a compilable piece of code that exhibit the error and an appropriate simple input file. I find it very difficult to get what you are exactly doing from your description. – Vladimir F Героям слава Jul 23 '14 at 13:45
  • Thank you for your interest. I hope my question is now clearer. – James Jul 23 '14 at 13:57
  • 6
    Please add declarations of all variables and how the main program looks like. Make a fully compilable example we can try. – Vladimir F Героям слава Jul 23 '14 at 14:01
  • 1
    From the snippet you've posted the first line of output ought to start `E = ` since the first executable statement after the `READ` prints the value of `E`. This makes it clear that there is a significant difference between the code you are having trouble with and the code you have shown us. You are asking us to waste our time debugging code you haven't shown us. – High Performance Mark Jul 23 '14 at 15:08
  • 1
    I'm going to guess that 8 is not the kind number of the default real. – francescalus Jul 23 '14 at 15:23

2 Answers2

2

You made the common error to forget the IMPLICIT NONE statement at the beginning of your program. (At least, it is heavily recommended to avoid this kind of error.)

As a result, all variables starting with I, J, K, L, M or N are of type INTEGER(4) and all other variables of type REAL(4). This means, that your variables A, B and C are of REAL(4). Passing them to the subroutine results in principle in an undetected type mismatch which results in misinterpreted values.

You should always place IMPLICIT NONE at the beginning of your programs and modules to be forced to specify explicit types for your variables!

Stefan
  • 2,460
  • 1
  • 17
  • 33
  • While this is good advice, you are perhaps over-stating the value of `implicit none` in the solution. Even with no implicit typing one still needs to know the correct declaration. – francescalus Jul 23 '14 at 18:37
  • @francescalus My experience with Fortran beginners tells me, that you can't state the value of `IMPLICIT NONE` enough. (The same would be true for integer division and float constants which aren't double precision per default...) But you are right, the focus should be the correct declaration of all variables. – Stefan Jul 23 '14 at 21:36
0

I think I have fixed this error by correcting prog1.f90:

PROGRAM prog1

    real(kind=8) :: A,B,C

    READ (5,*) A,B,C

    PRINT*, "A = ",A
    PRINT*, "B = ",B
    PRINT*, "C = ",C

    CALL test(A,B,C)


END PROGRAM prog1
James
  • 105
  • 3
  • 17
  • BTW, you should not rely on explicit kind numbers like 8, see http://stackoverflow.com/questions/3170239/fortran-integer4-vs-integer4-vs-integerkind-4 ) Also, relying on reading from unit 5 is not guaranteed to work. It is better to use `read(*,*)`. – Vladimir F Героям слава Jul 24 '14 at 07:23