Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
New Contributor I

warning #7799: %LOC is being stripped from argument

Jump to solution

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

Accepted Solutions
Highlighted
Black Belt

Ok, I see what's causing the

Jump to solution

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.

Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran

View solution in original post

0 Kudos
14 Replies
Highlighted
Valued Contributor II

The is a specific option at

Jump to solution

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
Highlighted
Black Belt

Seems to work for me...

Jump to solution

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) '

 

Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
0 Kudos
Highlighted
Valued Contributor II

Brooks are you using the

Jump to solution

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

0 Kudos
Highlighted
New Contributor I

Andrew, I am not using my own

Jump to solution

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
Highlighted
New Contributor I

Andrew, how do you access

Jump to solution

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
Highlighted
Valued Contributor II

transfer is intrinsic. c_loc

Jump to solution

transfer is intrinsic. c_loc is in USE ISO_C_BINDING

0 Kudos
Highlighted
Black Belt

Brooks, your comment about my

Jump to solution

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.)

Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
0 Kudos
Highlighted
New Contributor I

Steve, if I make your change

Jump to solution

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
Highlighted
Black Belt

I'm not understanding what

Jump to solution

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.

Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
0 Kudos
Highlighted
New Contributor I

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
Highlighted
New Contributor I

Steve,

 

Also I could not run your program because I get

INK : fatal error LNK1561: entry point must be defined

Brooks

0 Kudos
Highlighted
Black Belt
1 View

Ok, I see what's causing the

Jump to solution

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.

Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran

View solution in original post

0 Kudos
Highlighted
New Contributor I

Thanks very much Steve. That

Jump to solution

Thanks very much Steve. That fixed the problem!

Brooks

0 Kudos
Highlighted
Black Belt

This got fixed in 18.0.2.

Jump to solution

This got fixed in 18.0.2.

Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
0 Kudos