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

warning #7799: %LOC is being stripped from argument

Brooks_Van_Horn
New Contributor I
917 Views

I get a warning like warning #7799: %LOC is being stripped from argument which has REFERENCE and IGNORE_LOC attributes.   [ILEN] from a code ;like

       iret = RegQueryValueEx( hKey,    &
                              "Data4"C, &
                              NULL,     &
                              NULL,     &
                              LOC(Buff),&
                              LOC(iLen))

If I use just iLen rather than LOC(iLen) the call doesn't return a value representing the length of the registry value. iLen is declared as an Integer(4) variable. If I use the LOC() then I get the length of the registry value. So how do I code this so I don't get the warning but I do get the length correct?

I'm using VS2013 Community with PSXECE 2017 Rel 2.

Thanks,

Brooks

0 Kudos
1 Solution
Steve_Lionel
Honored Contributor III
917 Views

Ok, I see what's causing the warning about ILEN in x64 - the declaration in module ADVAPI32 uses INTEGER(LPDWORD) for that argument. That was correct when IGNORE_LOC and REFERENCE were not specified, but not now. It should be INTEGER(DWORD).  This mismatch is also what is causing ilen to not be set properly. The program I posted runs fine in 32-bit, but not 64-bit. You had not said earlier you were building for x64.

The only workaround I can think of is to make your own definition of the routine. For example:

INTERFACE 
FUNCTION RegQueryValueEx( &
        hKey, &
        lpValueName, &
        lpReserved, &
        lpType, &
        lpData, &
        lpcbData)
use ifwinty
  integer(LONG) :: RegQueryValueEx ! LONG
    !DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS:'RegQueryValueExA' :: RegQueryValueEx
  integer(HANDLE) hKey ! HKEY hKey
!DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: lpValueName
  character*(*) lpValueName ! LPCSTR lpValueName
  integer(LPDWORD) lpReserved ! LPDWORD lpReserved
!DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL, IGNORE_LOC :: lpType
  integer(DWORD) lpType ! LPDWORD lpType
  integer(LPBYTE) lpData ! LPBYTE lpData
!DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL, IGNORE_LOC :: lpcbData
  integer(DWORD) lpcbData ! LPDWORD lpcbData
 END FUNCTION
END INTERFACE

and then when you do the use, rename the bad one away:

use ADVAPI32, NotUsed => RegQueryValueEx

Note that I also fixed the declaration of lpType. One of the Intel folk, please ask the RTL people to fix this.

View solution in original post

0 Kudos
14 Replies
andrew_4619
Honored Contributor II
917 Views

There is a specific option that warns about %loc. A standard conforming but clumsy looking way is transfer(c_loc(var,0_handle)

0 Kudos
Steve_Lionel
Honored Contributor III
917 Views

Seems to work for me...

    program Console7
    use advapi32
    implicit none

    ! Variables
    character(100) :: buf
    integer(DWORD) :: ilen, ret
    integer(HANDLE) :: hkey
    
    ret = RegOpenKeyEx (HKEY_LOCAL_MACHINE, &
         "SOFTWARE\Microsoft\Windows\CurrentVersion"//""C, &
         0, &
         KEY_READ, &
         hkey)
    if (ret /= ERROR_SUCCESS) then
        print *, "Open Key failed with status ", ret
        stop
        end if
         
    ilen = len(buf)
    ret = RegQueryValueEx ( &
       hkey, &
        "ProgramFilesDir"//""C, &
        NULL, &
        NULL, &
        LOC(buf), &
        ilen)
    if (ret /= ERROR_SUCCESS) then
        print *, "Query failed with status ", ret
    else
        print '(A,A,A)',"Value is '",buf(1:ilen),"'"
    end if
        
    end program Console7
Value is 'C:\Program Files (x86) '

 

0 Kudos
andrew_4619
Honored Contributor II
917 Views

Brooks are you using the Intel version of of the RegQueryValueEx interface in IFWIN/advapi32 or are you supplying your own? 

0 Kudos
Brooks_Van_Horn
New Contributor I
917 Views

Andrew, I am not using my own. Steve, the reason your code works is that the returned value has a C type zero at the end. If you had left off the range of buf it still would have printed correctly but the value of iLen would still be 100. See my first comments.

Brooks

0 Kudos
Brooks_Van_Horn
New Contributor I
917 Views

Andrew, how do you access transfer(c_loc(var,0_handle). I can find neither C_LOC nor Transfer in the include files.

Brooks

0 Kudos
andrew_4619
Honored Contributor II
917 Views

transfer is intrinsic. c_loc is in USE ISO_C_BINDING

0 Kudos
Steve_Lionel
Honored Contributor III
917 Views

Brooks, your comment about my example is not correct. I modified it to print the value of ilen, and get:

Value is 'C:\Program Files (x86) ', length 23

The 23 includes the trailing NUL, which is why a blank prints at the end. Try it yourself.

If you still think there is a problem, please post your own example (using some common registry entry.)

0 Kudos
Brooks_Van_Horn
New Contributor I
917 Views

Steve, if I make your change i get  warning #6075: The data type of the actual argument does not match the definition.   [ILEN] which just replaces a warning about %LOC() to one of the wrong data type. I have to use Integer(PDWORD) rather than Integer(DWORD).

Brooks

0 Kudos
Steve_Lionel
Honored Contributor III
917 Views

I'm not understanding what you changed. All I was saying in post 8 was that I added ILEN to the PRINT statement - no other changes.

Please show a complete example that demonstrates the problem. Feel free to use my version as a starting point.

0 Kudos
Brooks_Van_Horn
New Contributor I
917 Views

Steve,

I took your code and put it into an x64 msvc project and compiled it. Here is what I got:

------ Build started: Project: Console7, Configuration: Debug x64 ------
1>Compiling with Intel(R) Visual Fortran Compiler 17.0.2.187 [Intel(R) 64]...
1>Console7.f90
1>c:\users\brooks\documents\visual studio 2013\Projects\Console7\Console7\Console7.f90(27): warning #6075: The data type of the actual argument does not match the definition.   [ILEN]


So reread my last post. Doing it your way gets rid of a warning for '%LOC()' but replaces it with a different warning of  #6073.

Brooks

0 Kudos
Brooks_Van_Horn
New Contributor I
917 Views

Steve,

 

Also I could not run your program because I get

INK : fatal error LNK1561: entry point must be defined

Brooks

0 Kudos
Steve_Lionel
Honored Contributor III
918 Views

Ok, I see what's causing the warning about ILEN in x64 - the declaration in module ADVAPI32 uses INTEGER(LPDWORD) for that argument. That was correct when IGNORE_LOC and REFERENCE were not specified, but not now. It should be INTEGER(DWORD).  This mismatch is also what is causing ilen to not be set properly. The program I posted runs fine in 32-bit, but not 64-bit. You had not said earlier you were building for x64.

The only workaround I can think of is to make your own definition of the routine. For example:

INTERFACE 
FUNCTION RegQueryValueEx( &
        hKey, &
        lpValueName, &
        lpReserved, &
        lpType, &
        lpData, &
        lpcbData)
use ifwinty
  integer(LONG) :: RegQueryValueEx ! LONG
    !DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS:'RegQueryValueExA' :: RegQueryValueEx
  integer(HANDLE) hKey ! HKEY hKey
!DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: lpValueName
  character*(*) lpValueName ! LPCSTR lpValueName
  integer(LPDWORD) lpReserved ! LPDWORD lpReserved
!DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL, IGNORE_LOC :: lpType
  integer(DWORD) lpType ! LPDWORD lpType
  integer(LPBYTE) lpData ! LPBYTE lpData
!DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL, IGNORE_LOC :: lpcbData
  integer(DWORD) lpcbData ! LPDWORD lpcbData
 END FUNCTION
END INTERFACE

and then when you do the use, rename the bad one away:

use ADVAPI32, NotUsed => RegQueryValueEx

Note that I also fixed the declaration of lpType. One of the Intel folk, please ask the RTL people to fix this.

0 Kudos
Brooks_Van_Horn
New Contributor I
917 Views

Thanks very much Steve. That fixed the problem!

Brooks

0 Kudos
Steve_Lionel
Honored Contributor III
917 Views

This got fixed in 18.0.2.

0 Kudos
Reply