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

Why won't this compile ?

WSinc
New Contributor I
1,197 Views

You can see from the uploaded example, that I am defining

POLYS exactly the same way in both called and calling routines.

 

for some reason the compiler does not think I am matching the types.

 

Is there something subtle I was supposed to do here?

 

Or should I abandon derived types in a calling sequence?

Maybe the compiler is not supposed to handle this?

 

BTW, It does not matter what order I compile them in.

0 Kudos
10 Replies
mecej4
Honored Contributor III
1,197 Views

If you read the documentation, you will find that (from the point of view of the compiler/Fortran standard) type definitions that you replicate in different program units are not considered equivalent.

You should place the type definition in a module, and USE that module wherever you need to declare variables of that type. You may also use the IMPORT statement where appropriate.

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,197 Views

Aside from mecej4's comment about using a module to declare the type...

The nc component of each of your type(poly)::p array have no been initialized.

Jim Dempsey

0 Kudos
andrew_4619
Honored Contributor III
1,197 Views

You use the . deliminaror rather than % for your type. This is some old type of non standard fortran extension and is confusing things.

1) jims comment - uninitilaised vars holds

2) i would use implicit none and declare the integers also

3) I put a module around it and tidied a couple of things, there are still problems that you need to fix but it will compile now.

[fortran]

  module zzzz
    type poly
      integer nc
      integer cf(0:20)
    end type
  contains
    
  function eval(p,x)
      real(8) :: eval
      real(8) :: x,y
      type(poly)::p
     y=0.D0
     do ic=0,p%nc-1
      y=y+p%cf(ic)*x**ic
     enddo
     eval=y
  end function eval
  subroutine pfit(npts,pts)
    integer npts
    real(8) :: pts(2,npts),x1,x2,y1,y2,dy1,dy2
    type(poly)::polys(100)
    !  the polynomial degree is no coeffs minus one.
    !  we assume that the number of pts is
    !  number of polynomials plus one.
    do ipt=2,npts
        ipoly=ipt-1
        !  supply the missing constant
        x1=pts(1,ipt-1)
        x2=pts(1,ipt)
        y1=eval(polys(ipoly),x1)
        y2=eval(polys(ipoly),x2)
        dy1=pts(2,ipt-1)-y1
        dy2=pts(2,ipt  )-y2
        !  do they agree ?
        if(abs(dy2-dy1) < 1.D-6)then
            !  yes
            polys(ipoly)%cf(0)=dy1
        else
            print *,"poly fit aborted ! "
            read (*,*)
        endif
    enddo ! ipt
  end subroutine
  end module zzzz

[/fortran]

0 Kudos
WSinc
New Contributor I
1,197 Views

Well, do I have to put everything in the same module?

I put the type declaration in a separate module and inserted a USE statement for the two routines.

As far as initializing the contents, thats done at execution time with READ statements

outside of these two routines. I just wanted to show the compile problem.

Apparently the compiler does not match the calling sequences unless a MODULE is being used.

I could have set the arrays to ZEROS of course, before execution.

 

I will try using a % sign instead of the period.

0 Kudos
andrew_4619
Honored Contributor III
1,197 Views

It is better the put the routines in a module as the interface of the sub-routines is known to the compiler whenever you 'use' that module. Note in pfit eval is not declared also as pfit knows all about eval as it is in the same module.

It saves time and errors to use modules

0 Kudos
dboggs
New Contributor I
1,197 Views

Unfortunately, if you are developing routines for a static library (maybe dll also, not sure), modules are not so convenient. After the routine is compiled, BOTH the .mod file and the .obj file must be made available to the developer who is using the library. The .obj file is placed in the library as usual, but the .mod file must be handled specially. It requires setting up a process where there is a standard location for storing the mod files, and the developer must set up a standard procedure for making them available to his project. Of course this can be done, but it is quite cumbersome compared to using a library routine without modules. (If you're trying to get your programming staff to use libraries, when the notion is new to them, this can be quite a stumbling block.)

0 Kudos
IanH
Honored Contributor III
1,197 Views

How is a mod file any different to a lib file in this regard?  You need a standard location for storing that...

The "coding safety" features associated with modules are compelling.

0 Kudos
dboggs
New Contributor I
1,197 Views

Ian,

With a lib file, you need one standard location and one standard method to include it, and that gives the developer complete access to every routine in the library. But if any of those routines use mod files, there will be another mod file for each one and they all have to be collected in another standard location so the developer can get access to those as well. It's about twice as much work or more, depending on how it's organized.

Modules are great, simple and easy as long as they only involve your own code, and you are in complete control of the source. If you want to make a mod distributable to other developers, without giving them access to the source, it is more work than using a lib.

One of the biggest problems I face is to educate a team of young Matlab afficionados about the benefits of Fortran, and the robustness and safety of modules is certainly one aspect of that. But they have trouble recognizing and appreciating this issue, and the added legwork associated with redistributing modules contributes to making it a hard sale.

0 Kudos
andrew_4619
Honored Contributor III
1,197 Views

It doesn't seem a big trip to stuff the .mod and .lib files into the folder and add this the the project search locations. The .mod is no different to the header files required by other languages.

One problem though is whist the lib is platform specific, the .mod is compiler specific so you need .mod files built with the right compiler (and often version). Perhaps the standards should have standardised this in some way...

 

 

0 Kudos
IanH
Honored Contributor III
1,197 Views

app4619 wrote:

One problem though is whist the lib is platform specific, the .mod is compiler specific so you need .mod files built with the right compiler (and often version). Perhaps the standards should have standardised this in some way...

Often enough the lib is compiler (and perhaps compiler options) specific too.  Not always, but often enough that you need to assume that is the case if you are coming up with any sort of general scheme for how/where you name/put files, etc.  Consider things like the descriptors for arrays, handling of IO, memory allocation.

I'd agree that more could be done by vendors to make the deployment of modules easier (ifort has one particularly annoying quirk - requiring all mod files for "child" modules to be present when a "parent" module is USE'd), but regardless, I still that cost/benefit considerations favours their use.

0 Kudos
Reply