Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner
43 Views

C_PTR and VALUE not respected on v17

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
Highlighted
Black Belt Retired Employee
43 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
Highlighted
Beginner
43 Views

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

0 Kudos
Highlighted
43 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
Highlighted
Beginner
43 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