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

LOC() function

dannycat
New Contributor I
1,387 Views
I am using the LOC() function to pass the address of an array to the Windows API GetCharWidth32() function.
When I compile as Win32 there is no problem but when I try compiling x64 I get a warning message indicating that there is a mismatch of 4th argument loc(wid). When I looked up the LOC function in the on-line documentation the first thing that surprised me was the second sentence which states "This function cannot be used as an actual argument." It seems OK to use itin Win-32 as it both compiles and operates in a desirable way but x64 seems to take exception. Does the statement only apply the x64 or is it not true. If it is then I guess the Win32 compiler should also flag up the mismatch.

In my original code I have:

integer :: wid(96)


iret = GetCharWidth32(hDC,32,127,loc(wid))

should I replace this with:

integer :: wid(96)
pointer :: (lpwid,wid)

lpwid = loc(wid)

iret = GetCharWidth32(hDC,32,127,lpwid)

What is the actual preferred method across all platforms?
0 Kudos
7 Replies
Jugoslav_Dujic
Valued Contributor II
1,387 Views
Quoting - dannycat
When I looked up the LOC function in the on-line documentation the first thing that surprised me was the second sentence which states "This function cannot be used as an actual argument." It seems OK to use itin Win-32 as it both compiles and operates in a desirable way but x64 seems to take exception. Does the statement only apply the x64 or is it not true. If it is then I guess the Win32 compiler should also flag up the mismatch.

In my original code I have:

integer :: wid(96)


iret = GetCharWidth32(hDC,32,127,loc(wid))

should I replace this with:

integer :: wid(96)
pointer :: (lpwid,wid)

lpwid = loc(wid)

iret = GetCharWidth32(hDC,32,127,lpwid)

What is the actual preferred method across all platforms?

"This function cannot be used as an actual argument" is misleading. That means that you cannot pass LOC itself as a callback (external), and I don't see why would anyone ever do that, so the statement, while true, is useless (remember the Helicopter joke?) . You surely can pass LOC(whatever) as an actual argument.


0 Kudos
Steven_L_Intel1
Employee
1,387 Views
The text in the manual refers to passing the name of the intrinsic LOC as an argument, not its use in an expression. For most intrinsics, you can pass the routine name as an argument to a routine that accepts it as EXTERNAL and call it. Not a commonly used feature.

I tried to reproduce the problem you describe but couldn't. Can you show a short but complete example that fails to compile? Here's what I used:

[plain]program test
use gdi32

integer (HANDLE) hdc
integer wid(96)

iret = GetCharWidth32 (hdc,32, 127, loc(wid))
end[/plain]
Note that hdc is declared as integer(HANDLE). If you had missed that, I would expect a complaint on the first argument, not the fourth.
0 Kudos
dannycat
New Contributor I
1,387 Views
The text in the manual refers to passing the name of the intrinsic LOC as an argument, not its use in an expression. For most intrinsics, you can pass the routine name as an argument to a routine that accepts it as EXTERNAL and call it. Not a commonly used feature.

I tried to reproduce the problem you describe but couldn't. Can you show a short but complete example that fails to compile? Here's what I used:

[plain]program test
use gdi32

integer (HANDLE) hdc
integer wid(96)

iret = GetCharWidth32 (hdc,32, 127, loc(wid))
end[/plain]
Note that hdc is declared as integer(HANDLE). If you had missed that, I would expect a complaint on the first argument, not the fourth.

Apologies Steve, I have put the wrong function in my initial post. The problem is with the function fglCallLists which has three arguments all integer*4 according to interface in ifopngl.f90.

In CVF I used:

use dfopngl

integer :: ls
character*20 :: string

call fglCallLists(ls,GL_UNSIGNED_BYTE, loc(string))

compiling inIVF 32-bit there seems toindicate no problem butIVF x64does not like the third argument. Should this argumentbe defined as a HANDLE in the ifopngl.f90 file? If it should is it safe for me to do this change?



0 Kudos
Jeffrey_A_Intel
Employee
1,387 Views
One difference between the IA-32 and Intel 64 platforms is the return type of %LOC. It's INTEGER(4) on IA-32 and INTEGER(8) on Intel 64 (and IA-64).
0 Kudos
Steven_L_Intel1
Employee
1,387 Views
This is an error in the declaration of fglCallLists. The argument should be declared as an address-sized integer. I'll get it fixed.

The correct declaration would be:

[plain]interface
subroutine fglCallLists (n ,type ,lists )
!DEC$ ATTRIBUTES DEFAULT :: fglCallLists
!DEC$ ATTRIBUTES STDCALL, DECORATE,ALIAS : 'glCallLists' :: fglCallLists
import
integer(K_GLsizei) n
integer(K_GLenum) type
integer(K_GLvoid), DIMENSION(*) :: lists
!DEC$ ATTRIBUTES NO_ARG_CHECK, IGNORE_LOC :: lists
end subroutine fglCallLists
end interface[/plain]
This would allow you to pass the array directly or pass loc(array).
0 Kudos
dannycat
New Contributor I
1,387 Views
This is an error in the declaration of fglCallLists. The argument should be declared as an address-sized integer. I'll get it fixed.

The correct declaration would be:

[plain]interface
subroutine fglCallLists (n ,type ,lists )
!DEC$ ATTRIBUTES DEFAULT :: fglCallLists
!DEC$ ATTRIBUTES STDCALL, DECORATE,ALIAS : 'glCallLists' :: fglCallLists
import
integer(K_GLsizei) n
integer(K_GLenum) type
integer(K_GLvoid), DIMENSION(*) :: lists
!DEC$ ATTRIBUTES NO_ARG_CHECK, IGNORE_LOC :: lists
end subroutine fglCallLists
end interface[/plain]
This would allow you to pass the array directly or pass loc(array).

Thanks Steve, I've used the above as a work around. I see if it works when I overcome the next hurdle! Will this fix be captured for the next release?
0 Kudos
Steven_L_Intel1
Employee
1,387 Views
I hope so - just found about a half-dozen other routines needing a similar fix. For the release I'm not going to do the NO_ARG_CHECK thing so just use LOC where needed.
0 Kudos
Reply