X64 against WIN32

X64 against WIN32

Dear All:

I recently got a new Dell computer, put Windows7 64 bit and the Intel Fortran Compiler 64 bit onto the machine, after I updated my licence. I did not mean to do it. This is the latest IVF that is not beta.

I had not used this flavour, its telling me the following error upon running a program that has complied nicely before.

Warning 3 warning #6075: The data type of the actual argument does not match the definition. [LPARAM] B:\\Users\\John\\Documents\\Visual Studio 2010\\Projects\\CX1Reader4\\CX1Reader4\\CX1Reader4_mod.f90 539

cxClient = loword(lParam)

cyClient = hiword(lParam)

it is upset at the loword being a DWORD and the lParam is a long_ptr.

Is there a difference from WIN32 to WIN64 for these two types? Is there a fix?

Thanks

JMN

32 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Windows items need to be typed in a manner which automatically tracks 32- or 64-bits; these "universal" types are present in IFWINTY; here are the usual Windows proc arguments:

INTEGER(HANDLE),  INTENT(IN)   :: hwnd

INTEGER(UINT),    INTENT(IN)   :: msg

INTEGER(fWPARAM), INTENT(IN)   :: wParam

INTEGER(fLPARAM), INTENT(IN)   :: lParam

Paul:

Thanks for the response.

I tried to download the 32 bit IVF, but we have had power outages all afternoon, but I just got it. I took off the X64 and loaded both back on. (Steve this is not beta, this is real Fortran)

Considering the various sources for this program , my own poor windows skills it is a wonder it runs at all, well actually it only runs because of much kind help here over the last few years.

It compiled and ran in 32 bit, so I need to go slowly through all of the calls and check the types against the IFWINTY module and the interfaces for the subroutines. It is not a trivial exercise, pretty much like writing it for the first time.

I am going to integrate the program into a 2012 SQL Server database using the German SQL Fortran routines, I am hoping they arrive tomorrow. Accountant type says they have paid for them, so fingers crossed. Out IT types do not like SQL Server.

Should be a lot of fun.

JMN

Dear Steve:

It has taken a while to get a small windows program that runs nicely and will start me to do some real Fortran programming, whilst feelling slightly younger than a DEC 32 computer. I have it running under 32 bit as noted above, but there are a few quirky errors which I was wondering if you would look at in 64 bit compiler to tell me I am at least headed in the right and true path.

This program comes from many sources, including great help by Anthony Richards, Petzold's book, the great CVF book by Lawrence and yourself. I am not sure how many copyright owenreships I am breaching by putting the code here, but I am happy if anyone wants to try it, if there are errors please let me know.

PS: The code has source control embedded, just ignore it.
PS1:I chose the colour as tribute to Trapper John who wanted a Robin's egg blue convertible.

JMN

Attachments: 

AttachmentSize
Downloadapplication/zip InstronAnalysis.zip1.05 MB

Hi John --

Steve is on a well-deserved vacation, so won't get back to you until he's back.

We'll have the "second-string" take a look at your program -- I did download it, and got one error building (and a handful of warnings). Is that what you saw too?

--Lorri

Lorri:

It is ok, you are talking to a third string man, so you are still in front.

Yes, the warnings are interesting, but the error had me stuck.

As I liberated the code as I went I was hoping to put it back onto this site so other third stringers like me had a model that worked in IVF modern instead of CVF Olde Englishe for a simple Windows program that works in Fortran. It is not pretty, it could be turned into modules, but it doth worketh. Slowly like me.

thanks
JMN.

Hi John,

The error and warning are caused by using 4byte integers as pointers. In 32bit mode, pointers are 4bytes so this works, but in 64bit mode pointers are 8bytes.

You can work around the error by changing the lastargument passed to the functionDialogBoxParam on line 894 of InstronAnalysis_mod.f90. Instead of passing 0 for the pointer, pass "0_long_ptr" or "0_8"

I would suggest changing your code so that the pointer size is set automatically though.

Regards,
Annalee

function HiWord (param)

import

integer(WORD) :: HiWord

!DEC$ ATTRIBUTES DEFAULT :: HiWord

!DEC$ IF DEFINED(_M_IX86)

!DEC$ ATTRIBUTES STDCALL, ALIAS : '_HiWord@4' :: HiWord

!DEC$ ELSE

!DEC$ ATTRIBUTES STDCALL, ALIAS :  'HiWord'   :: HiWord

!DEC$ ENDIF

integer(DWORD) param

end function HiWord

end interface

interface !lib=ifwin.lib

function LoWord (param)

import

integer(WORD) :: LoWord

!DEC$ ATTRIBUTES DEFAULT :: LoWord

!DEC$ IF DEFINED(_M_IX86)

!DEC$ ATTRIBUTES STDCALL, ALIAS : '_LoWord@4' :: LoWord

!DEC$ ELSE

!DEC$ ATTRIBUTES STDCALL, ALIAS :  'LoWord'   :: LoWord

!DEC$ ENDIF

integer(DWORD) param

end function LoWord

end interface

Dear Annalee:

I am not the world's best on pointers and such, but for the warning the LOWORD macro is defined with DWORD and LONG_PTR, in IFWINTY, LONG_PTR is variable but DWORD is fixed at 4. So it works at 32 but gives warning at 64, whereas there is a DWORDLONG, so why not use it?

Or am I completly lost?

JMN

I looked at InstronAnalysis_mod.f90 and concluded it would be a long hard slog.I only got through a few hundred lines and found a few things that look like errors.

InstronAnalysis_mod.f90

109: !integer*4 ret

139: integer(HANDLE) hbrush

163ff:     lpszClassName   =   "InstronAnalysis"//ACHAR(0)

197ff:        brush%lbStyle = BS_SOLID

420: integer(LONG) iSBheight

421: integer cxWidth, iStep, i ! A guess


Just about any specification statement in a Windows program that writes out the number of bytes of an integer kind as an integer literal is suspect. Line 109 seems superfluous because ret is declared but never used. Perhaps you can get ifort to warn you about this? Line 139 is fatal because CreateBrushIndirect (just look up CreateBrushIndirect MSDN) returns an HBRUSH, which (look up Windows data types MSDN) is a HANDLE and so will be promoted on translation to x64. Lines 163 ff. are a needless DVF extension, as are lines 197 ff. which will cause problems if you try to catch errors en masse by requesting standards checking. There was no good reason to specify integer(2) in lines 420-421, and I ran out of energy there.

The Lawrence book is the best place to start Windows Fortran programming, but it was written before MicroSoft introduced 64-bit Windows and is not at all 64-bit safe. The only thing I know to do is to examine each INTEGER declaration with literal KIND number (e.g. INTEGER(4) x instead of INTEGER(HANDLE) x) and check the usage of the variable in question via MSDN and replace the literal with the appropriate name as illustrated in the above paragraph. The book's web site has the examples in the book and more; it would be nice if someone could update those examples to be 64-bit safe and fix errors and unnecessary extensions.

Dear Repeat Offender:

Thank you for the comments. This is probably the most useful set from the Lawrence book, I am happy to fix it, just need to learn the X64 pointer stuff. Actually hating pointers does not help, but I will try.

Yes I know it is a long slog, it was a long slog to get this working in 32 as I had to learn Windows and C, whilst going deeply into the Fortran include files, and it was a long slog to get a Windows Driver to compile in Visual Studio 2010 instead of the WDK compilers, so now I can attach blinking lights to my programs to tell me there are high pressures in a system without having to look at the data.

I created a searchable PDF of all of the Fortran include files so I could get this working in 32 and then lost it. Looks like I am doing it again.

Thanks again.

JMN

The warnings are all over the place, and I saw lots of good suggestions about how to fix them.

But, the error, the actual "sticking point" is in your file instronAnalysis_mod.f90, line 894.

The code is:

ret = DialogBoxParam(ghInstance,LOC(lpszName),hWnd, LOC(Dialog1), 0)

but should be

ret = DialogBoxParam(ghInstance,LOC(lpszName),hWnd, LOC(Dialog1), 0_LONG_PTR)

(Note: you have it specified that way in your other call to DialogBoxParam, around line 972)

--Lorri

Is there a list somewhere of all of the Win32 and x64 types that we need to be aware of when changing our projects to x64?

There does not seem to be many references in the compiler documentation to x64 and nothing about migrating applications.

Thanks,

David

I don't know of a list but all the types are near the top of ifwinty.f90 and the are comments there also. I just refer to that and to the API declarations documentation on the MSDN websites. You generally find the 'names' in the two locations tend to match up pretty well so minimal thinking is needed.  

Typically problems occur when the program author takes shortcuts and doesn't use the defined kinds from the Windows interface modules. If the kinds are used, there is typically little issue porting programs to 64-bits.

Steve - Intel Developer Support

Cita:

David White escribió:

Is there a list somewhere of all of the Win32 and x64 types that we need to be aware of when changing our projects to x64?

There does not seem to be many references in the compiler documentation to x64 and nothing about migrating applications.

Thanks,

David

If time and resources allow you, I suggest shooting for a goal of ZERO types that need any special handling when upgrading projects to X64 from WIN32; this can be done by making use of standard Fortran features for KIND definitions and standard intrinsic modules such as ISO_C_BINDING and ISO_FORTRAN_ENV.  At times, one may need to make use of an Intel extension e.g., INT_PTR_KIND() where Intel takes care of the architecture differences so the program author doesn't to include any platform-specific code.

Well, yes, that's the whole point of iNT_PTR_KIND() allowing you to address the difference without relying on a module.

Steve - Intel Developer Support

Where is the documentation for INT_PTR_KIND and other Win32/x64 considerations?  There are only a handful of hits on x64 in the documentation.

David

I don't like INT_PTR_KIND because it's DVF/CVF/IFORT specific. I prefer C_INTPTR_T from the ISO_C_BINDING module, or something like INT_PTR from IFWIN (is it in there?), or even getting the KIND of a cray pointer is more transportable:

 

program p
   implicit none
!   integer(int_ptr_kind()) iptr ! fails on gfortran
   integer idummytarget
   pointer(idummypointer,idummytarget)
   integer(kind(idummypointer)) iptr
   write(*,*) bit_size(iptr)
end program p

But the main thing is to look up the function you are invoking in MSDN, and then going to http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx to get a translation if required and then using the appropriate KIND from IFWIN. For other compilers you can write your own partial IFWIN as necessary.

Well, sure, if you're willing to use ISO_C_BINDING, and you should, then by all means use C_INTPTR_T.  But you should never, ever hard-code the kind in your code. If you're using the IFWIN declarations, constants for the various Windows API kinds are defined there.

Steve - Intel Developer Support

Cita:

Steve Lionel (Intel) escribió:

Well, sure, if you're willing to use ISO_C_BINDING, and you should, then by all means use C_INTPTR_T.  But you should never, ever hard-code the kind in your code. If you're using the IFWIN declarations, constants for the various Windows API kinds are defined there.

Steve,

Is there any thought at Intel to update modules for Windows programming such as IFWINTY, KERNEL32, etc. to use standard Fortran as much as possible, perhaps by making available a new set of "standard" modules for your users?  That is, per Repeat Offender's comment in Quote #19, can most references to INT_PTR_KIND() in IFWINTY be replaced with C_INTPTR_T from ISO_C_BINDING and if so, won't offering some solutions involving standard Fortran be a really nice feature for your users?  And over the long term, this may help reduce the support "burden" on Intel if more and more Windows programming users make use of standard-conforming types.

That sort of change would make no difference. As we have made changes to the API modules we have used more standard syntax and features where we can (for example, IMPORT). But by their very nature, the API modules are non-portable so it makes little sense to rewrite them. Besides, we already use constants such as DWORD and LPVOID in the declarations.

In some cases, we can add as alternates interfaces that pass typed variables by reference rather than address by value, but we can't do that in all cases.

I'd rather put the effort into adding declarations for the new functions Microsoft added. We're working on that but it's slow progress.

Steve - Intel Developer Support

As I sit here looking at my Fortran not dead mug, I keep thinking - but not doing - we need a Dr. Fortran T shirt.

Something like:

Who needs TARDIS, we have Dr. Fortran!

Dr. Fortan designed a new TARDIS before lunch.

Chuck met the Doctor on the battlefield, Chuck's dead.

But really I got onto the web site and found a very old post had suddenly sprung to life again.

You know for a while I played with putting Fortran programs into a form with buzz and windows and then decided - LIFE IS TO FREAKING SHORT FOR THIS ________.

Although MKL is an interesting reading companion at night. 

Real question :  in the kind stuff, the number gets set as 1_long for instance, what exactly does 1_long mean?

JMN

 

 

1_long means 1 of type INTEGER(long). This assumes that LONG has been declared as an integer named constant (PARAMETER) with a value that is acceptable to the processor an integer kind value. There is such a definition in module IFWINTY:

    integer, parameter :: LONG   = 4        ! INTEGER(4) 

 

Steve - Intel Developer Support

But where would you use it?

    integer, parameter :: LONG   = 4        ! INTEGER(4) 

 

given this - why say

1_long ?

 

Reid et al do it in their book, but there is no explanation

JMN

You happened to pick a bad example since,with IFort, integers of kind=4 happen to be the same as default integers. Think about integers that you want to be of kind=2 or 8. Note, too, that kind numbers are not portable, as has been discussed in these forums. You may consider using SELECTED_INT_KIND to make your code completely portable.

Also, explicitly specifying the kind insulates you from changes in the default kind, say with the /I8 option. It's just good practice. It's more important for things that may vary by platform, such as Windows API handles.

Steve - Intel Developer Support

consider using SELECTED_INT_KIND to make your code completely portable. - I am trying to

I will copy the section from the book - it is not easy to follow what the heck they are talking about

JMN

Dear All:

I enclose the early page from Metcalf, Reid and Cohen on integer Literal Constants.

In their book this is the only place it is mentioned and the only sample. But why would I use a constant

1_k6 for example and where?

So is this the intended use:

integer, parameter :: k6 = selected_int_kind(6)

kind(2_K6)

Does that mean that the number kind(2_K6) is kind that will hold a 2 to the power k6 number?

Really weird syntax given the very limited machine types.

My wife says she used a VAX at Purdue in the 80's.

JMN

Attachments: 

AttachmentSize
Downloadimage/jpeg IMG001.jpg1.2 MB

selected_int_kind(6) returns the smallest kind (if any) that will hold a signed 6 decimal digit number (not 2**6). If you don't specify the kind on a constant you get the default kind, which may not be what you want.

Steve - Intel Developer Support

Cita:

John Nichols escribió:

.. why would I use a constant 1_k6 for example and where?

..

I think the unwritten rule (at least in my part of the world) is to use as few literal constants (i.e., avoid "magic" numbers) as possible and isolate them in appropriate "data" modules via named constants.  With that in mind, there might be a few occasions when one has to use them.  For example, say one is doing some chemical reaction analysis on molecules and needs to include elemental balance and may have code such as:

    ...
    USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : INT32
    ..
    INTEGER, PARAMETER :: I4 = INT32
    ..
    TYPE :: Molecule
           ..
           INTEGER(I4), ALLOCATABLE :: Formula(:)
           ..
    END TYPE Molecule
    ..
    TYPE(Molecule) :: H2O
    ..
    H2O%Formula = [ 2_i4, 1_i4 ]
    ..
           

Cita:

John Nichols escribió:

Does that mean that the number kind(2_K6) is kind that will hold a 2 to the power k6 number?

As explained by Metcalf et al., the number kind(2_k6) can generally hold values in the range -999999 to +999999 since Fortran doesn't have the concept of unsigned integers.

Cita:

Really weird syntax given the very limited machine types.

I'm quite empathetic to Fortran Standards creators, starting with Fortran 90 where a lot of such syntax was first established - one can only imagine the kind of pressure they were under to please folks in so many quarters and with conflicting demands and so forth.  Considering how "beautiful" and "flexible" and remarkable modern Fortran is, I think a little bid of weirdness here and there only adds to the charm!

I think most coders can simply make do with ISO_FORTRAN_ENV (or ISO_C_BINDING) and the defined kinds therein, at least I do.  With a coding goal of no "magic" numbers and working with named constants only, the weird syntax need only appear in a few places.

 

I'm quite empathetic to Fortran Standards creators, starting with Fortran 90 where a lot of such syntax was first established - one can only imagine the kind of pressure they were under to please folks in so many quarters and with conflicting demands and so forth.  Considering how "beautiful" and "flexible" and remarkable modern Fortran is, I think a little bid of weirdness here and there only adds to the charm!

I think most coders can simply make do with ISO_FORTRAN_ENV (or ISO_C_BINDING) and the defined kinds therein, at least I do.  With a coding goal of no "magic" numbers and working with named constants only, the weird syntax need only appear in a few places.

Creating standards is a nightmare - almost as bad as blind peer review, there are a few peer reviewers who are blind, deaf and dumb IMHO.

Now I understand - avoid magic numbers.

Thanks

JMN

 

Leave a Comment

Please sign in to add a comment. Not a member? Join today