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

Argument mismatch

albert
Beginner
2,485 Views
Dear All.

I have the following code:

subroutine a2
integer :: arg1 = 12
integer :: arg2 = 22
write(*,*)'Routine a2'
call psd(arg1,arg2)
call psd1(arg1)
write(*,*)'End routine a2'
end subroutine a2

subroutine a1
integer :: arg1 = 11
integer :: arg2 = 21
write(*,*)'Routine a1'
call psd(arg1)
call psd1(arg1,arg2)
write(*,*)'End routine a1'
end subroutine a1

As we can see theer is a problem with the calls to psd and psd1 but the linker reports only problems with psd1@4. It looks like the compiler makes of the call to psd in a1 a PSD@8 call as it had to do in a2.

I have attached a tar file with all reuired files.

Fortran version: 10.1.019

Is this a compiler bug ?

best Regards,

Albert
0 Kudos
12 Replies
jimdempseyatthecove
Honored Contributor III
2,485 Views

Albert,

(not being from Intel)

If I were to guess as to the problem...

psd and psd1 are external to the source and, as written above, do not have a subroutine interface declaration. Without the interface declaration, the first use (my guess) declares an expected interface. In the first subroutine, a2, psd was used with 2 args, psd1 with one arg.Thus declaring the argument type(s) and number to both external subroutines. In the second subroutine, a1, a call to psd with one arg is made, i.e. calling a two arg subroutine with one missing argument. This is permitted for subroutines with optional arguments. Note having the subroutine within the source nor having an interface declaration, the compiler assumes this is your intention. The call to psd1 in a1 is a different situation because it is adding an argument to a previously assumed interface.

Jim Dempsey
0 Kudos
ArturGuzik
Valued Contributor I
2,485 Views
Quoting - albert
Dear All.

I have the following code:

subroutine a2
integer :: arg1 = 12
integer :: arg2 = 22
write(*,*)'Routine a2'
call psd(arg1,arg2)
call psd1(arg1)
write(*,*)'End routine a2'
end subroutine a2

subroutine a1
integer :: arg1 = 11
integer :: arg2 = 21
write(*,*)'Routine a1'
call psd(arg1)
call psd1(arg1,arg2)
write(*,*)'End routine a1'
end subroutine a1

As we can see theer is a problem with the calls to psd and psd1 but the linker reports only problems with psd1@4. It looks like the compiler makes of the call to psd in a1 a PSD@8 call as it had to do in a2.

I have attached a tar file with all reuired files.

Fortran version: 10.1.019

Is this a compiler bug ?

best Regards,

Albert
Hi,

my guess is the PSD is an interface name, so compiler recognizes it can take one or two arguments, while psd1 is one of routines inside PSD interface and accepts only one argument. Anyway, it doesn't look as a (compiler) bug.

Is this power spectrum density routine from NR?

A.

EDIT: I submitted the post exactly the same time Jim did. His reply is obviously much better and thorough. I will also know that if web page loads the post enormously long it means somebody else replies at the same time.

0 Kudos
albert
Beginner
2,485 Views
Quoting - ArturGuzik
Hi,

my guess is the PSD is an interface name, so compiler recognizes it can take one or two arguments, while psd1 is one of routines inside PSD interface and accepts only one argument. Anyway, it doesn't look as a (compiler) bug.

Is this power spectrum density routine from NR?

A.

EDIT: I submitted the post exactly the same time Jim did. His reply is obviously much better and thorough. I will also know that if web page loads the post enormously long it means somebody else replies at the same time.



The problem did occur with a power spectrum density routine, but I stripped it and only left the name. The PSD function is not from NR.

Albert
0 Kudos
albert
Beginner
2,485 Views

Albert,

(not being from Intel)

If I were to guess as to the problem...

psd and psd1 are external to the source and, as written above, do not have a subroutine interface declaration. Without the interface declaration, the first use (my guess) declares an expected interface. In the first subroutine, a2, psd was used with 2 args, psd1 with one arg. Thus declaring the argument type(s) and number to both external subroutines. In the second subroutine, a1, a call to psd with one arg is made, i.e. calling a two arg subroutine with one missing argument. This is permitted for subroutines with optional arguments. Note having the subroutine within the source nor having an interface declaration, the compiler assumes this is your intention. The call to psd1 in a1 is a different situation because it is adding an argument to a previously assumed interface.

Jim Dempsey

Jim,

I can see the point of generating an expected (implicit) interface. This would be an interface without optional arguments, the standard specifies (ISO/IEC 1539-1, paragraph 12.3.1) that in case of optional arguments an explicit interface is required, therefore I would have expected an error message on the second use.

Albert

0 Kudos
Steven_L_Intel1
Employee
2,485 Views
I remember a bug that sounds a lot like this. It was fixed some time ago. Try using a current compiler (11.1.). Or, unless you really need it, turn off use of STDCALL by setting External Routines > Calling Convention to "Default".
0 Kudos
albert
Beginner
2,485 Views
I remember a bug that sounds a lot like this. It was fixed some time ago. Try using a current compiler (11.1.). Or, unless you really need it, turn off use of STDCALL by setting External Routines > Calling Convention to "Default".


I've installed version 11.1.048 (20090930) and the problem remains.
I do need the /iface:cvf. Even when I could remove this option the problem still remains only it will occur during runtime.

Albert
0 Kudos
Steven_L_Intel1
Employee
2,485 Views
Ok, I can reproduce the problem. I will comment that if you build with /warn:interface that you'll get a compile-time error for this - your program is simply incorrect. If you have a need to call a STDCALL routine of the same name with different numbers of arguments, I suggest defining a generic for it along the lines as follows:

[plain]module psdmod
interface psd
  subroutine psd_1arg (arg1)
  !DEC$ ATTRIBUTES DECORATE,ALIAS:"psd" :: psd_1arg
  integer arg1
  end subroutine psd_1arg
  subroutine psd_2arg (arg1,arg2)
  !DEC$ ATTRIBUTES DECORATE,ALIAS:"psd" :: psd_2arg
  integer arg1
  integer arg2
  end subroutine psd_2arg
end interface
interface psd1
  subroutine psd1_1arg (arg1)
  !DEC$ ATTRIBUTES DECORATE,ALIAS:"psd1" :: psd1_1arg
  integer arg1
  end subroutine psd1_1arg
  subroutine psd1_2arg (arg1,arg2)
  !DEC$ ATTRIBUTES DECORATE,ALIAS:"psd1" :: psd1_2arg
  integer arg1
  integer arg2
  end subroutine psd1_2arg
end interface

end module



      subroutine a2
      use psdmod
         integer :: arg1 = 12
         integer :: arg2 = 22
         write(*,*)'Routine a2'
         call psd(arg1,arg2)
         call psd1(arg1)
         write(*,*)'End routine a2'
      end subroutine a2

      subroutine a1
      use psdmod
         integer :: arg1 = 11
         integer :: arg2 = 21
         write(*,*)'Routine a1'
         call psd(arg1)
         call psd1(arg1,arg2)
         write(*,*)'End routine a1'
      end subroutine a1
[/plain]

0 Kudos
albert
Beginner
2,485 Views
Ok, I can reproduce the problem. I will comment that if you build with /warn:interface that you'll get a compile-time error for this - your program is simply incorrect. If you have a need to call a STDCALL routine of the same name with different numbers of arguments, I suggest defining a generic for it along the lines as follows:



I fully agree that the program I supplied is incorrect. In my opinion the problem is that I think the compiler / linker should have found this problem. in a1 the "decorations" should be psd@4 and psd1@8 and in a2 psd@8 and psd@4 but this is not the case. When I look into the aa.obj I can only find psd@8 and psd1@4.
In our real program we made a similar mistake and only psd@8 was there although psd@4 should have been there as welli, the implementation was only available for psd@8 thus the compiler / linker didn't find it but it crashed during runtime)


When using the suggested /warn:interface I get an error message about psd1 but not about psd.
aa.f90(6): error #6631: A non-optional actual argument must be present when invoking a procedure with an explicit interface. [ARG2]
call psd1(arg1)
--------------^

Albert
0 Kudos
Steven_L_Intel1
Employee
2,485 Views

The linker would not have found the problem because the compiler had already decided that a single routine has a single entry point. I do agree that the compiler should have noticed both errors and will suggest this to the developers. If you had built with /warn:interface, which has been the default in new Visual Studio projects since 10.0, you would have caught at least one of these. I note that CVF caught both errors.
0 Kudos
albert
Beginner
2,485 Views

The linker would not have found the problem because the compiler had already decided that a single routine has a single entry point. I do agree that the compiler should have noticed both errors and will suggest this to the developers. If you had built with /warn:interface, which has been the default in new Visual Studio projects since 10.0, you would have caught at least one of these. I note that CVF caught both errors.

Thanks for the effort and giving the feedback to the developers.
In my case the /warn:interface would not have helped, I had in my code the version with psd (I added psd1 in the example for completeness).

I don't understand "I note that CVF caught both errors" as I used /iface:cvf and it only caught the psd1 one.

Albert
0 Kudos
Steven_L_Intel1
Employee
2,485 Views

When I say CVF I mean CVF, and not /iface:cvf.

C:ProjectsU69035>df -c aa.f90
Compaq Visual Fortran Optimizing Compiler Version 6.6 (Update C)
Copyright 2003 Compaq Computer Corp. All rights reserved.

aa.f90
aa.f90(34) : Warning: Routine PSD called with different number and/or type of actual arguments in earlier call - C attribute required if intended.
call psd(arg1,arg2)
--------------^
aa.f90(35) : Warning: Routine PSD1 called with different number and/or type of actual arguments in earlier call - C attribute required if intended.
call psd1(arg1)
--------------^

I have a vague memory of complaining about losing this detection before. Let me see what I can find. I do think that /warn:interface should have picked up on both errors.
0 Kudos
albert
Beginner
2,485 Views

When I say CVF I mean CVF, and not /iface:cvf.

C:ProjectsU69035>df -c aa.f90
Compaq Visual Fortran Optimizing Compiler Version 6.6 (Update C)
Copyright 2003 Compaq Computer Corp. All rights reserved.

aa.f90
aa.f90(34) : Warning: Routine PSD called with different number and/or type of actual arguments in earlier call - C attribute required if intended.
call psd(arg1,arg2)
--------------^
aa.f90(35) : Warning: Routine PSD1 called with different number and/or type of actual arguments in earlier call - C attribute required if intended.
call psd1(arg1)
--------------^

I have a vague memory of complaining about losing this detection before. Let me see what I can find. I do think that /warn:interface should have picked up on both errors.


Steve,

The Compaq Visual Fortran (Before it has been Digital wasn't it) had slipped my mind.

I agree /warn:interface should have detected both errors.

Albert
0 Kudos
Reply