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

C_PTR and VALUE not respected on v17

bluequartz
Beginner
329 Views
I have the following "C" call back declaration; typedef void (*ProgCallBackType2)(size_t, int, int, float); I am trying to call that from Fortran but I get garbage coming through. It works perfectly on GFortran (under linux and macOS). Here are the relevant Fortran bits: ! similar callback routine, with two integer arguments ABSTRACT INTERFACE SUBROUTINE ProgressCallBack2(objAddress, loopCompleted, totalLoops, bseYield) USE, INTRINSIC :: ISO_C_BINDING INTEGER(c_size_t),INTENT(IN), VALUE :: objAddress INTEGER(KIND=4), INTENT(IN), VALUE :: loopCompleted INTEGER(KIND=4), INTENT(IN), VALUE :: totalLoops REAL(KIND=4),INTENT(IN), VALUE :: bseYield END SUBROUTINE ProgressCallBack2 END INTERFACE Then down in the actual Fortran function we make the call: !-------------------------------------------------------------------------- recursive subroutine EMsoftCgetMCOpenCL(ipar, fpar, atompos, atomtypes, latparm, accum_e, accum_z, cproc, objAddress, cancel) & bind(c, name='EMsoftCgetMCOpenCL') ! this routine is callable from a C/C++ program !DEC$ ATTRIBUTES DLLEXPORT :: EMsoftCgetMCOpenCL TYPE(C_FUNPTR), INTENT(IN), VALUE :: cproc integer(c_size_t),INTENT(IN), VALUE :: objAddress character(len=1),INTENT(IN) :: cancel integer(kind=irg) :: cn, dn, totn real(kind=sgl),target :: bseyield ...... call proc(objAddress, cn, totn, bseyield) Back on the C++ side of things I have the following as my Callback function: void MonteCarloSimulationControllerProgress(size_t instance, int loopCompleted, int totalLoops, float bseYield) { std::cout << "MonteCarloSimulationControllerProgress: " << instance << "\t" << loopCompleted << "\t" << totalLoops << "\t" << bseYield << std::endl; } When I run the program I get utter garbage as the variables. They are not pointers, the actual values are not correct and they are not pointers to pointers (that I can tell). I'm very much a beginner at Fortran (I am working to call this Fortran module from C++) but looking around on Google seems to indicate that we have setup our Fortran code correctly (as evidenced by it working from GFortran). While trying to figure out what was going on I acted on a hunch and changed the "C" side of things to be the following: typedef void (*ProgCallBackType2)(size_t*, int*, int*, float*); void MonteCarloSimulationControllerProgress(size_t* instance, int* loopCompleted, int* totalLoops, float* bseYield) { std::cout << "MonteCarloSimulationControllerProgress: " << *instance << "\t" << *loopCompleted << "\t" << *totalLoops << "\t" << *bseYield << std::endl; } And now I get all the proper values passed through. It seems like Fortran is still passing by reference even though we told it by value? If I leave these changes then GFortran segfaults when running? This is with version 17.0.4.210 with a build on JULY 2016. Is this a known bug? I can't move to a newer compiler because our fortran code will ICE the next revision of the IFORT so we stuck with this version. Help. I'm lost.
0 Kudos
4 Replies
Steve_Lionel
Honored Contributor III
329 Views

The Fortran standard says that VALUE, by itself, passes a writeable copy by reference. If the procedure declaration includes BIND(C), then it does mean pass-by-value. Earlier versions of Intel Fortran didn't get this right, treating VALUE as always meaning pass-by-value. I think it was version 16 that changed this. /assume:nostd_value reverts to the old behavior.

I haven't quite sorted out all you wrote, but I note that the abstract interface ProgressCallback2 doesn't include BIND(C).

If this doesn't help, please attach a small but complete test case that demonstrates the problem.

0 Kudos
bluequartz
Beginner
329 Views

Thank You so much. The bind(c) solved the problem.

0 Kudos
Lorri_M_Intel
Employee
329 Views

Quick question to the OP --- did you (or your company) report the ICE in your sources?    That way, we can fix it and you'll be able to move on if necessary.

            thanks -

                         --Lorri

0 Kudos
bluequartz
Beginner
329 Views
Unfortunately we did not. Which as a software developer is NOT what I would want to hear but it boiled down to time. I would either have had to reduce the issue down to something small that I could give you or give you access to our entire project. I'm not a regular Fortran developer as my main language is C++. I am working with a collaborator who writes the Fortran and I access the Fortran from our C++ Gui so reducing the issue down to something small and reproducible would be beyond my capabilities. Looks like Update 4 is working correctly for us so that is the solution for us. What ever you updated/fixed between update 2 and update 4 seems to have fixed our issue. My collaborator also only develops on macOS and Linux where they use GFortran and I am keeping the cross platform going by running nightly builds on our Windows 10 machine. Such are academic research projects on shoestring budgets. I do appreciate the followup.
0 Kudos
Reply